void history_remember(history_t* past, char* parameter, U16 frame, int function, float value, interpolation_t* inter)
{
    past->lastFrame = frame;
    state_t* state = dict_lookup(past->states, parameter);
    if (state) //should always be true
    {
	state_t* next = state_new(frame, function, value, inter);
	state_append(state, next);
    }
    else
    	syntaxerror("Internal error: changing parameter %s, which is unknown for the instance.", parameter);
}
Exemplo n.º 2
0
/* Read and dispatch incoming request(s). */
static int
gotrequest(void * cookie, int status)
{
	struct dispatch_state * D = cookie;
	struct proto_lbs_request * R;
	uint32_t blklen;
	uint64_t nextblk;

	/* We're no longer waiting for a packet to arrive. */
	D->read_cookie = NULL;

	/* If the wait failed, the connection is dead. */
	if (status)
		goto drop;

	/* Read packets until there are no more or an error occurs. */
	do {
		/* Allocate space for a request. */
		if ((R = malloc(sizeof(struct proto_lbs_request))) == NULL)
			goto err0;

		/* Attempt to read a request. */
		if (proto_lbs_request_read(D->readq, R))
			goto drop1;

		/* If we have no request, stop looping. */
		if (R->type == PROTO_LBS_NONE)
			break;

		/* Handle the request. */
		switch (R->type) {
		case PROTO_LBS_PARAMS:
			warn0("PROTO_LBS_PARAMS is not implemented");
			warn0("Update to a newer version of kvlds");
			goto drop1;
		case PROTO_LBS_PARAMS2:
			state_params(D->S, &blklen, &nextblk);
			if (proto_lbs_response_params2(D->writeq, R->ID,
			    blklen, nextblk, nextblk - 1))
				goto err1;
			free(R);
			break;
		case PROTO_LBS_GET:
			D->npending += 1;
			if (state_get(D->S, R, callback_get, D))
				goto err1;
			break;
		case PROTO_LBS_APPEND:
			state_params(D->S, &blklen, &nextblk);
			if (R->r.append.blklen != blklen)
				goto drop2;
			if ((R->r.append.blkno != nextblk) ||
			    (D->appendip != 0)) {
				if (proto_lbs_response_append(D->writeq,
				    R->ID, 1, 0))
					goto err2;
				break;
			}
			D->npending += 1;
			D->appendip = 1;
			if (state_append(D->S, R, callback_append, D))
				goto err1;
			break;
		case PROTO_LBS_FREE:
			if (deleteto_deleteto(D->D, R->r.free.blkno))
				goto err1;
			if (proto_lbs_response_free(D->writeq, R->ID))
				goto err1;
			free(R);
			break;
		default:
			/* proto_lbs_request_read broke. */
			assert(0);
		}
	} while (1);

	/* Free the (unused) request structure. */
	free(R);

	/* Wait for more requests to arrive. */
	if ((D->read_cookie = wire_readpacket_wait(D->readq,
	    gotrequest, D)) == NULL) {
		warnp("Error reading request from connection");
		goto err0;
	}

	/* Success! */
	return (0);

drop2:
	free(R->r.append.buf);
drop1:
	free(R);
drop:
	/* We didn't get a valid request.  Drop the connection. */
	dropconnection(D);

	/* All is good. */
	return (0);

err2:
	free(R->r.append.buf);
err1:
	free(R);
err0:
	/* Failure! */
	return (-1);
}
void history_rememberSweep(history_t* past, U16 frame, float x, float y, float r, int clockwise, int short_arc, interpolation_t* inter)
{
    float lastX, lastY, dX, dY;
    U16 lastFrame;

    past->lastFrame = frame;
    state_t* change = dict_lookup(past->states, "x");
    if (change) //should always be true
    {
    	while (change->next)
    	    change = change->next;
    	lastFrame = change->frame;
    	lastX = change->value;
    	change = dict_lookup(past->states, "y");
    	if (change) //should always be true
    	{
    	    while (change->next)
    	    	change = change->next;
    	    lastY = change->value;
    	    dX = x - lastX;
    	    dY = y - lastY;
    	    if (dX == 0 && dY == 0)
	    	syntaxerror("sweep not possible: startpoint and endpoint must not be equal");
   	    if ((dX) * (dX) + (dY) * (dY) > 4 * r * r)
	    	syntaxerror("sweep not possible: radius is to small");
    	    if (change->frame > lastFrame)
    	    {
    	    	lastFrame = change->frame;
    	    	history_remember(past, "x", lastFrame, CF_JUMP, lastX, 0);
    	    }
    	    else
    	    	if (change->frame < lastFrame)
    	    	    history_remember(past, "y", lastFrame, CF_JUMP, lastY, 0);
    	    float c1X, c1Y, c2X, c2Y;
    	    if (dX == 0) //vertical
    	    {
    	    	c1Y = c2Y = (lastY + y) / 2;
    	    	c1X = x + sqrt(r * r - (c1Y - y) * (c1Y - y));
    	    	c2X = 2 * x -c1X;
    	    }
    	    else
	    	if (dY == 0) //horizontal
    	    	{
    	    	    c1X = c2X = (lastX + x) / 2;
    	    	    c1Y = y +sqrt(r * r - (c1X - x) * (c1X - x));
    	    	    c2Y = 2 * y -c1Y;
    	    	}
    	    	else
    	    	{
    	    	    c1X = sqrt((r * r - (dX * dX + dY * dY) / 4) / (1 + dX * dX / dY / dY));
    	    	    c2X = -c1X;
    	    	    c1Y = -dX / dY * c1X;
    	    	    c2Y = -c1Y;
    	    	    c1X += (x + lastX) / 2;
    	    	    c2X += (x + lastX) / 2;
    	    	    c1Y += (y + lastY) / 2;
    	    	    c2Y += (y + lastY) / 2;
    	    	}
    	    float angle1, angle2, delta_angle, centerX, centerY;
    	    angle1 = getAngle(lastX - c1X, lastY - c1Y);
    	    angle2 = getAngle(x - c1X, y - c1Y);
    	    delta_angle = getDeltaAngle(angle1, angle2, clockwise);
    	    if ((short_arc && fabs(delta_angle) <= M_PI) || (! short_arc && fabs(delta_angle) >= M_PI))
    	    {
    	        centerX = c1X;
    	        centerY = c1Y;
    	    }
    	    else
    	    {
	        angle1 = getAngle(lastX - c2X, lastY - c2Y);
    		angle2 = getAngle(x - c2X, y - c2Y);
    	    	delta_angle = getDeltaAngle(angle1, angle2, clockwise);
    	    	centerX = c2X;
    	    	centerY = c2Y;
    	    }
    	    change = dict_lookup(past->states, "x");
	    state_t* nextX = state_new(frame, CF_SWEEP, x, inter);
	    nextX->arc.r = r;
	    nextX->arc.angle = angle1;
	    nextX->arc.delta_angle = delta_angle;
	    nextX->arc.cX = centerX;
	    nextX->arc.cY = centerY;
	    nextX->arc.X = 1;
	    state_append(change, nextX);
    	    change = dict_lookup(past->states, "y");
	    state_t* nextY = state_new(frame, CF_SWEEP, y, inter);
	    nextY->arc.r = r;
	    nextY->arc.angle = angle1;
	    nextY->arc.delta_angle = delta_angle;
	    nextY->arc.cX = centerX;
	    nextY->arc.cY = centerY;
	    nextY->arc.X = 0;
	    state_append(change, nextY);
    	}
    	else
    	    syntaxerror("Internal error: changing parameter y in sweep, which is unknown for the instance.");
    }
    else
    	syntaxerror("Internal error: changing parameter x in sweep, which is unknown for the instance.");
}