Esempio n. 1
0
File: node.c Progetto: hydra/freewpc
/* Insert an unbound ball into a node. */
void node_insert (struct ball_node *node, struct ball *ball)
{
    unsigned int offset;

    if (ball->node)
    {
        simlog (SLC_DEBUG, "node_insert: %s already at %s",
                ball->name, ball->node->name);
        return;
    }

    if (node_full_p (node) || !node->type)
    {
        simlog (SLC_DEBUG, "node_insert: %s not allowed", node->name);
        return;
    }

    offset = (node->head + node->count) % node->size;
    node->ball_queue[offset] = ball;
    node->count++;
    ball->node = node;
    ball->pos = offset;
    if (node->type->insert)
        node->type->insert (node, ball);
#ifdef CONFIG_UI
    ui_update_ball_tracker (ball->index, node->name);
#endif
    simlog (SLC_DEBUG, "node_insert: added %s to %s, count=%d", ball->name, node->name, node->count);

    if (node->unlocked && !node_full_p (node->next))
        sim_time_register (100, FALSE, (time_handler_t)node_kick_delayed, node);
}
Esempio n. 2
0
/**
 * Move a ball to a specific location.
 */
void sim_ball_move (unsigned int ballno, unsigned int location)
{
	unsigned int prev_location;

	if (ballno == -1)
		return;

	/* Remove the ball from its previous location */
	prev_location = sim_ball_location[ballno];
	if (prev_location != SIM_LOCATION_NONE)
	{
		sim_location_toggle (prev_location);
		sim_location_ball[location] = SIM_NO_BALL_HERE;
	}

	/* Set the ball at the new location */
	sim_location_toggle (location);
	sim_ball_location[ballno] = location;
	sim_location_ball[location] = ballno;
#ifdef CONFIG_UI
	ui_update_ball_tracker (ballno, location);
#endif
	simlog (SLC_DEBUG, "Ball %d @ %s", ballno, sim_ball_location_name (location));
}
Esempio n. 3
0
File: node.c Progetto: hydra/freewpc
/* Move a ball from one location to another.  The two nodes do not
	have to be connected via the default topology. */
void node_move (struct ball_node *dst, struct ball_node *src)
{
    struct ball *ball;

    if (!dst || !src)
        return;

    /* If there are already too many balls in the destination, then
    don't allow the operation: it must remain where it is. */
    if (node_full_p (dst))
    {
        simlog (SLC_DEBUG, "node_kick %s: destination %s is full", src->name, dst->name);
        return;
    }

    ball = node_remove (src);
    if (!ball)
    {
        simlog (SLC_DEBUG, "node_kick: no balls in %s", src->name);
        return;
    }

    simlog (SLC_DEBUG, "node_kick: %s -> %s", src->name, dst->name);
    /* If no delay is associated with a movement from the source, then
    the move is instantaneous.  Otherwise, it will be performed later; in
    the meantime the ball is not associated with any node. */
    if (src->delay == 0)
        node_insert (dst, ball);
    else
    {
#ifdef CONFIG_UI
        ui_update_ball_tracker (ball->index, src->name);
#endif
        node_insert_delay (dst, ball, src->delay);
    }
}
Esempio n. 4
0
File: node.c Progetto: hydra/freewpc
/* Remove the head of the node queue. */
struct ball *node_remove (struct ball_node *node)
{
    unsigned int offset;
    struct ball *ball;

    if (node->count == 0)
    {
        simlog (SLC_DEBUG, "node_remove: no balls in %s", node->name);
        return NULL;
    }

    offset = node->head % node->size;
    ball = node->ball_queue[offset];
    if (!ball)
    {
        simlog (SLC_DEBUG, "node_remove: count=%d but ball is null?", node->count);
        return NULL;
    }

    node->head++;
    node->count--;
    ball->node = NULL;
    if (node->type->remove)
        node->type->remove (node, ball);
#ifdef CONFIG_UI
    ui_update_ball_tracker (ball->index, "Free");
#endif
    simlog (SLC_DEBUG, "node_remove: took %s from %s", ball->name, node->name);

    if (node->prev && node->prev->unlocked && node->prev->count != 0)
    {
        node_kick (node->prev);
    }

    return ball;
}