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); }
/* 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."); }