示例#1
0
bool pback_should_cont(node_t *node, int8_t cont)
{
    /* CONT_NONE: Never continue.
     * CONT_LEAF: Continue to the end of the current branch, over leaves only.
     * CONT_BRANCH: Continue to the end of the played branch.
     * CONT_SIBLINGS: Continue to the end of the played branch and all its siblings.
     * CONT_ALL, Always continue.
     */
    
    switch (cont)
    {
        case CONT_NONE:
            info("cont_none\n");
            return false;
        case CONT_ALL:
            info("cont_all\n");
            return true;

        case CONT_LEAF:
            info("cont_leaf: is leaf: %d, pars equal: %d\n", node_isleaf(node), node->par == lists.leaf->par);
            return (node_isleaf(node) && (node->par == lists.leaf->par));

        case CONT_BRANCH:
            info("cont_branch: lists.play is par: %d\n", node_ispar(lists.play, node));
            return node_ispar(lists.play, node);
            
        case CONT_SIBLINGS:
            info("cont_siblings: lists.play->par is par: %d\n", node_ispar(lists.play->par, node));
            return node_ispar(lists.play->par, node);

        default:
            info("pback_should_cont(): Bad value '%d'.\n", cont);
            return false;
    }
}
示例#2
0
point_t*
insert_(quadtree_t* tree, node_t *root, point_t *point, bool update) {
  if (node_isempty(root)) {
    root->point = point;
    return point;
  } else if (node_isleaf(root)) {
    if (root->point->x == point->x && root->point->y == point->y) {
      if(update) {
        reset_node_(tree, root);
        root->point = point;
        point = NULL;
        return root->point;
      } else {
        return root->point;
      }
    } else {
      if (!split_node_(tree, root)) return NULL;
      return insert_(tree, root, point, update);
    }
  } else if (node_ispointer(root)) {
    node_t* quadrant = get_quadrant_(root, point);
    if(!quadrant) return NULL;
    return insert_(tree, quadrant, point, update);
  }
  return NULL;
}
示例#3
0
state_t pback_decide(pback_t *pback)
{
    state_t state;
    node_t *cur = NULL;
    
    if (lists.leaf != NULL)
    {
        /* If there are any nodes in the queue, we want to start the first one. */
        if (g_opts.pl.usequeue && (lists.queue.list.br->count > 0))
        {
            /* Find the node in the playlist matching the first queue track. */
            if (node_isleaf(lists.queue.list.br->head))
                cur = node_findleaf(&lists.pl.list, lists.queue.list.br->head->t->fn.str);
            else
                cur = node_findbranch(&lists.pl.list, lists.queue.list.br->head->br->type, lists.queue.list.br->head->br->name.str);
    
            if (cur != NULL) /* found the track */
            {
                /* Record the current track so we can jump back to it later if
                 * we want to. */
                lists.saveleaf = lists.leaf;
                lists.delleaf = lists.queue.list.br->head;
                state = OK;
            }
            else
                state = ERR_NULL;
        }
        else
        {
            cur = lists.leaf;
            state = pback_getnew(&cur, DOWN);
        }
    }
    else
    {
        error("pback_decide(): lists.leaf was NULL, nothing to decide.\n");
        state = ERR_NULL;
    }

    if ((cur != NULL) && (state == OK))
    {
        if ((state = pback_play_node(pback, cur, TR_FLOW)) == OK)
            info("pback_decide(): started.\n");
        else
            error("pback_decide(): couldn't start ('%s').\n", err_tostr(state));
    }
    else
        info("pback_decide(): Some error occurred earlier, not attempting to start playback.\n");
    
    return state;
}
示例#4
0
point_t*
find_(node_t* node, double x, double y) {
  if (node_isleaf(node)) {
    if (node->point->x == x && node->point->y == y) {
      return node->point;
    }
  } else {
    point_t test;
    test.x = x;
    test.y = y;
    return find_(get_quadrant_(node, &test), x, y);
  }

  return NULL;
}
示例#5
0
state_t pback_getnew(node_t **node, int8_t dir)
{
    state_t state;
    node_t *tmp = *node,
           *last;

    while (true)
    {
        last = tmp;
        tmp = node_traverse(tmp, dir, 1);

        if ((tmp == NULL) /* no more tracks */
            || (tmp == last)) /* no more visible tracks */
            break;

        if (node_isleaf(tmp))
        {
            if (tmp->t->avail && tmp->t->sane) /* found a playable track */
                break;

            info("pback_getnew(): ignoring %s%s%s track %s.\n",
                !tmp->t->avail ? "unavailable" : "",
                !(tmp->t->avail || tmp->t->sane) ? " and " : "",
                !tmp->t->sane ? "insane" : "",
                tmp->t->fn);
        }
        else /* found a branch -- always 'playable' */
            break;
    }
    
    if (tmp == *node) /* nowhere visible to go */
        state = ERR_VIS;
    else if (tmp == NULL) /* nowhere at all to go */
        state = ERR_NULL;
    else /* got a new track */
    {
        if (pback_should_cont(tmp, g_opts.tr.cont))
        {
            *node = tmp;
            state = OK;
        }
        else
            state = ERR_RULES;
    }
    
    return state;
}
示例#6
0
state_t pback_play_node(pback_t *pback, node_t *node, int8_t mode)
{
    state_t state;
    node_t *cur;
    
    if (node != NULL)
    {
        if (node_isleaf(node))
            cur = node;
        else
            for (cur = node->br->head; node_isbranch(cur) && (cur->br->head != NULL); cur = cur->br->head);
        
        if (cur != NULL)
        {
            if (cur->t != NULL)
            {
                lists.play = node;

                if ((state = pback_play_leaf(pback, cur, mode)) == OK)
                {
                    /* success */
                }
                else
                    info("pback_play_node(): pback_play_leaf() failed!\n");
            }
            else
            {
                error("pback_play_node(): A trackless node!\n");
                state = ERR_BADNODE;
            }
        }
        else
        {
            error("pback_play_node(): That branch has no leaves!\n");
            state = ERR_NODE;
        }
    }
    else
    {
        error("pback_play_node(): Called on NULL node!\n");
        state = ERR_NULL;
    }
    
    return state;
}
示例#7
0
/**
 * Find points in bbox
 *
 * quadtree_within(quadtree_t *tree, bbox_t *bbox, results_t *results)
 * @return void
 */
void
quadtree_within(node_t *root, bounds_t *bounds, within_callback_t cb) {
  if (node_isleaf(root)) {
    cb(root->point);
  } else {
    if (root->sw && bounds_intersect(bounds, root->sw)) {
      quadtree_within(root->sw, bounds, cb);
    }
    if (root->se && bounds_intersect(bounds, root->se)) {
      quadtree_within(root->se, bounds, cb);
    }
    if (root->nw && bounds_intersect(bounds, root->nw)) {
      quadtree_within(root->nw, bounds, cb);
    }
    if (root->ne && bounds_intersect(bounds, root->ne)) {
      quadtree_within(root->ne, bounds, cb);
    }
  }
}
示例#8
0
state_t pback_start_strands(pback_t *pback, node_t *leaf, int8_t mode)
{
    state_t state;
    
    /* check if libao is initialised */
    if (!g_data.started.audio)
    {
        error("pback_start_strands(): libao isn't running! Bailing out.\n");
        return ERR_AUDIO;
    }

    /* make sure we're not trying to play a branch */
    if (!node_isleaf(leaf))
    {
        error("pback_start_strands(): node parameter wasn't a leaf! Bailing out.\n");
        return ERR_NODE;
    }
    
    /* If we weren't already playing, make a buffer and an output strand. */
    if (mode == TR_START)
    {
        buf_init(&pback->buf, g_opts.au.numbufs);
        strand_outp_init(&pback->outp, &pback->buf, &leaf->t->au, &pback->outp.state);
    }
    /* Otherwise, delete the old decoder; a new one will be made below. */
    else
    {
        strand_uninit(&pback->dec);
        
        /* If we're changing to a new track immediately, flush the buffer. */
        if (mode == TR_CHANGE)
            buf_flush(&pback->buf);

        /* If the output strand encountered an error, it should also be
         * restarted. */
        if (IS_ERR(pback->outp.state))
        {
            buf_flush(&pback->buf);
            strand_uninit(&pback->outp);
            strand_outp_init(&pback->outp, &pback->buf, &leaf->t->au, &pback->outp.state);
        }
    }
    
    /* Now, create the new decoder. This is done every time a new track is
     * started, for obvious reasons. */
    if (pback->dec.inited)
    {
        warn("pback_start_strands(): decoder already inited.\n");
        strand_uninit(&pback->dec);
    }
    
    strand_dec_init(&pback->dec, leaf->t, &pback->buf, fmt_getfmts()[leaf->t->au.fmt], &pback->dec.state);
   
    if ((state = strand_setup(&pback->dec)) == OK) /* the decoder is happy */
    {
        pback->dec.state = ST_STARTING;
        
        if ((state = strand_start(&pback->dec)) == OK) /* The decoder is running */
        {
            /* the decoder started, so wipe the slate clean for this track */
            leaf->t->avail = true;
            leaf->t->sane = true;
            
            lists.newleaf = leaf;
            
            if ((mode == TR_START) || IS_ERR(pback->outp.state)) /* The output strand must also be started */
            {
                if ((state = strand_setup(&pback->outp)) == OK) /* the output strand is happy */
                {
                    pback->outp.state = ST_STARTING;

                    if ((state = strand_start(&pback->outp)) == OK) /* The output strand is running */
                    {
                        g_data.state = ST_PLAYING;
						pback->buf.lock = false;
                        
                        state = OK;
                    }
                    else
                    {
                        info("pback_start_strands(): strand_start(pback->outp) failed!\n");
                        pback->outp.state = state;
                    }
                }
                else
                {
                    info("pback_start_strands(): strand_setup(&pback->outp) failed!\n");
                    pback->outp.state = state;
                }
            }
            else /* the output strand was already running */
            {
				pback->buf.lock = false;
                state = OK;
            }
        }
        else
        {
            info("pback_start_strands(): strand_start(pback->dec) failed!\n");
            pback->dec.state = state;
        }
    }
    else
    {
        info("pback_start_strands(): strand_setup(&pback->dec) failed!\n");
        pback->dec.state = state;
        leaf->t->sane = false;
    }
   
    return state;
}