ETERM *body_copy(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *from_idp = erl_element(3, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; int from_body_id = ERL_INT_VALUE(from_idp); erlmunk_body *from_b; HASH_FIND_INT(s->bodies, &from_body_id, from_b); // DEBUGF(("copying location from body #%d(%p) to #%d(%p)", // from_body_id, from_b, body_id, b)); // copy position and angle from the from body cpBodySetPosition(b->body, cpBodyGetPosition(from_b->body)); cpBodySetAngle(b->body, cpBodyGetAngle(from_b->body)); cpBodySetVelocity(b->body, cpBodyGetVelocity(from_b->body)); return NULL; }
ETERM *body_apply_impulse(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *impulsep = erl_element(3, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; // apply the impulse at the center of the body and along it's current angle float angle = deg_to_rad(cpBodyGetAngle(b->body)); cpVect angleV = cpvforangle(angle); cpVect impulse = cpvmult(angleV, ERL_FLOAT_VALUE(impulsep)); cpBodyApplyImpulseAtWorldPoint(b->body, impulse, angleV); return NULL; }
ETERM *body_update_position(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *deltap = erl_element(3, argp); erlmunk_space *s = NULL; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; cpVect position = cpBodyGetPosition(b->body); float angle = deg_to_rad(cpBodyGetAngle(b->body)); cpVect angleV = cpvforangle(angle); cpVect projection = cpvmult(angleV, ERL_FLOAT_VALUE(deltap)); cpVect new_position = cpvadd(projection, position); cpBodySetPosition(b->body, new_position); // DEBUGF(("body_update_position(x: %f, y: %f, delta: %f) has succeeded (x: %f, y: %f)", // position.x, position.y, ERL_FLOAT_VALUE(deltap), // new_position.x, new_position.y)); return NULL; }
int main() { ETERM *tuplep, *intp; ETERM *fnp, *argp; int res; byte buf[100]; long allocated, freed; erl_init(NULL, 0); while (read_cmd(buf) > 0) { tuplep = erl_decode(buf); fnp = erl_element(1, tuplep); argp = erl_element(2, tuplep); if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) { res = foo(ERL_INT_VALUE(argp)); } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 17) == 0) { res = bar(ERL_INT_VALUE(argp)); } intp = erl_mk_int(res); erl_encode(intp, buf); write_cmd(buf, erl_term_len(intp)); erl_free_compound(tuplep); erl_free_term(fnp); erl_free_term(argp); erl_free_term(intp); } }
ETERM *body_get_user_data(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; erlmunk_body_data *data = cpBodyGetUserData(b->body); ETERM *datap = erl_copy_term(data->term); ETERM *atom_ok = erl_mk_atom("ok"); ETERM **body_get_data_array = (ETERM **) malloc(sizeof(ETERM*) * 2); body_get_data_array[0] = atom_ok; body_get_data_array[1] = datap; ETERM *body_get_data_tuple = erl_mk_tuple(body_get_data_array, 2); free(body_get_data_array); ETERM *reply_tuple = erl_mk_reply(fromp, body_get_data_tuple); ETERM *gen_cast_tuple = erl_mk_gen_cast(reply_tuple); return gen_cast_tuple; }
ETERM *body_set_position(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *vectorp = erl_element(3, argp); ETERM *xp = erl_element(1, vectorp); ETERM *yp = erl_element(2, vectorp); erlmunk_space *s = NULL; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; cpBodySetPosition(b->body, cpv(ERL_FLOAT_VALUE(xp), ERL_FLOAT_VALUE(yp))); // DEBUGF(("body_set_position(x: %f, y: %f) has succeeded", // ERL_FLOAT_VALUE(xp), ERL_FLOAT_VALUE(yp))); return NULL; }
ETERM *space_add_body(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *massp = erl_element(3, argp); // ETERM *inertiap = erl_element(4, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int object_id = ERL_INT_VALUE(idp); cpBody *body = cpSpaceAddBody(s->space, cpBodyNew(ERL_FLOAT_VALUE(massp), INFINITY)); // the body is created inactive, it is explicitly activated // when all it's values have been set. cpBodySleep(body); erlmunk_body_data *data = malloc(sizeof(erlmunk_body_data)); data->id = object_id; data->term = NULL; cpBodySetUserData(body, (cpDataPointer) data); space_add_body_hash(s, object_id, body); return NULL; }
ETERM * new_image_blank(ETERM *arg, int c_node) { int stride, cbufsize, status, key_length; ETERM *width, *height; cairo_context *ctx = NULL; width = erl_element(1, arg); height = erl_element(2, arg); stride = ERL_INT_VALUE(width) * 4; cbufsize = ERL_INT_VALUE(height) * stride; ctx = malloc(sizeof(cairo_context)); if (ctx) { ctx->cbuf = (byte *)malloc(cbufsize); if (ctx->cbuf) { memset(ctx->cbuf, 0, cbufsize); ctx->sf = cairo_image_surface_create_for_data(ctx->cbuf, CAIRO_FORMAT_ARGB32, ERL_INT_VALUE(width), ERL_INT_VALUE(height), stride); ctx->cr = cairo_create(ctx->sf); return erl_format("{c_node, ~i, {ok, ~i}}", c_node, ctx); } else { free(ctx); return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } erl_free_term(width); erl_free_term(height); }
ETERM *space_remove_body(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; // DEBUGF(("removing body #%d\n", body_id)); // remove the user data associated with the body erlmunk_body_data *data = cpBodyGetUserData(b->body); if (data->term != NULL) erl_free_compound(data->term); free(data); cpBodyEachShape(b->body, shapeRemove, NULL); cpSpaceRemoveBody(s->space, b->body); space_remove_body_hash(s, b); cpBodyDestroy(b->body); cpBodyFree(b->body); return NULL; }
ETERM *body_set_collision_circle(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *radiusp = erl_element(3, argp); ETERM *collision_typep = erl_element(4, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; cpShape *shape = cpSpaceAddShape(s->space, cpCircleShapeNew(b->body, ERL_FLOAT_VALUE(radiusp), cpvzero)); cpShapeSetCollisionType(shape, ERL_INT_VALUE(collision_typep)); // DEBUGF(("body_set_collision_circle has succeeded")); return NULL; }
int main() { ETERM *tuplep; ETERM *fnp; ETERM *args; byte buf[100]; const char* func_name; #ifdef __WIN32__ /* Attention Windows programmers: you need [to pay Serge Aleynikov a * beer because he's the one who figured out how to get this to work * on windows :)] explicitly set mode of stdin/stdout to binary or * else the port program won't work. */ _setmode(_fileno(stdout), _O_BINARY); _setmode(_fileno(stdin), _O_BINARY); #endif eNotify_init(); erl_init(NULL, 0); while (read_cmd(buf) > 0) { tuplep = erl_decode(buf); fnp = erl_element(1, tuplep); func_name = (const char*)ERL_ATOM_PTR(fnp); args = erl_element(2, tuplep); // MATCH FIRST! -> REMEMBER THAT! if (strncmp(func_name, "get_error_desc", 14) == 0) { local_get_error_desc(args); } else if (strncmp(func_name, "add_watch", 9) == 0) { local_add_watch(args); } else if (strncmp(func_name, "remove_watch", 12) == 0) { local_remove_watch(args); } else { byte buf[10]; ETERM *nok = erl_mk_atom("undef"); // alloc nok erl_encode(nok, buf); write_cmd(buf, erl_term_len(nok)); erl_free_term(nok); // free nok } erl_free_compound(tuplep); erl_free_term(fnp); } return 0; }
int main(int argc, char **argv) { int fd; /* fd to Erlang node */ int loop = 1; /* Loop flag */ int got; /* Result of receive */ unsigned char buf[BUFSIZE]; /* Buffer for incoming message */ ErlMessage emsg; /* Incoming message */ ETERM *fromp, *tuplep, *fnp, *argp, *resp; int res; erl_init(NULL, 0); if (erl_connect_init(1, "secretcookie", 0) == -1) erl_err_quit("erl_connect_init"); if ((fd = erl_connect("e1@hostname")) < 0) erl_err_quit("erl_connect"); fprintf(stderr, "Connected to e1@hostname\n\r"); while (loop) { got = erl_receive_msg(fd, buf, BUFSIZE, &emsg); if (got == ERL_TICK) { /* ignore */ } else if (got == ERL_ERROR) { loop = 0; } else { if (emsg.type == ERL_REG_SEND) { fromp = erl_element(1, emsg.msg); tuplep = erl_element(2, emsg.msg); fnp = erl_element(1, tuplep); argp = erl_element(2, tuplep); if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) { res = foo(ERL_INT_VALUE(argp)); } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) { res = bar(ERL_INT_VALUE(argp)); } resp = erl_format("{cnode, ~i}", res); erl_send(fd, fromp, resp); erl_free_term(emsg.from); erl_free_term(emsg.msg); erl_free_term(fromp); erl_free_term(tuplep); erl_free_term(fnp); erl_free_term(argp); erl_free_term(resp); } } } }
ETERM * translate(ETERM* arg, int c_node) { ETERM *tx, *ty; cairo_context *ctx = get_cairo_context(arg); if (ctx) { tx = erl_element(2, arg); ty = erl_element(3, arg); cairo_translate(ctx->cr, val(tx), val(ty)); erl_free_term(tx); erl_free_term(ty); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * scale(ETERM* arg, int c_node) { ETERM *sx, *sy; cairo_context *ctx = get_cairo_context(arg); if (ctx) { sx = erl_element(2, arg); sy = erl_element(3, arg); cairo_scale(ctx->cr, val(sx), val(sy)); erl_free_term(sx); erl_free_term(sy); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * rel_line_to(ETERM* arg, int c_node) { ETERM *x, *y; cairo_context *ctx = get_cairo_context(arg); if (ctx) { x = erl_element(2, arg); y = erl_element(3, arg); cairo_rel_line_to(ctx->cr, val(x), val(y)); erl_free_term(x); erl_free_term(y); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
int main(int argc, char **argv) { int fd; /* file descriptor of Erlang node */ int loop = 1; /* Loop flag */ int got; /* Result of receive */ unsigned char buf[BUFSIZE]; /* Buffer for incoming message */ ErlMessage emsg; /* Incoming message */ ETERM *fromp, *argp, *resp; /* Reps of Erlang terms */ int res; /* Result of the fac call */ /* initialize erl_interface (once only) */ erl_init(NULL, 0); /* initialize the connection mechanism */ if (erl_connect_init(1, "refactorcookie", 0) == -1) erl_err_quit("erl_connect_init"); /* connect to a running Erlang node */ if ((fd = erl_connect("blah@Simon-Thompsons-Computer-2")) < 0) erl_err_quit("erl_connect"); while (loop) { /* message received */ got = erl_receive_msg(fd, buf, BUFSIZE, &emsg); if (got == ERL_TICK) { /* ignore */ } else if (got == ERL_ERROR) { loop = 0; } else { if (emsg.type == ERL_REG_SEND) { /* unpack message fields */ fromp = erl_element(1, emsg.msg); argp = erl_element(2, emsg.msg); /* call fac and send result back */ resp = erl_format("{ok, ~i}", fac(ERL_INT_VALUE(argp))); erl_send(fd, fromp, resp); /* free the term storage used */ erl_free_term(emsg.from); erl_free_term(emsg.msg); erl_free_term(fromp); erl_free_term(argp); erl_free_term(resp); } } } }
ETERM * select_font_face(ETERM* arg, int c_node) { ETERM *family, *slant, *weight; cairo_context *ctx = get_cairo_context(arg); if (ctx) { family = erl_element(2, arg); slant = erl_element(3, arg); weight = erl_element(4, arg); cairo_select_font_face(ctx->cr, (char *)ERL_ATOM_PTR(family), ERL_INT_VALUE(slant), val(weight)); erl_free_term(family); erl_free_term(slant); erl_free_term(weight); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * surface_destroy(ETERM* arg, int c_node) { ETERM *surface; surface = erl_element(1, arg); cairo_surface_destroy(ptr(surface)); erl_free_term(surface); return erl_format("{c_node, ~i, ok}", c_node); }
ETERM * surface_get_height(ETERM* arg, int c_node) { ETERM *surface; surface = erl_element(1, arg); int h = cairo_image_surface_get_height(ptr(surface)); erl_free_term(surface); return erl_format("{c_node, ~i, {ok, ~i}}", c_node, h); }
ETERM * set_source_surface(ETERM* arg, int c_node) { ETERM *surface, *x, *y; cairo_context *ctx = get_cairo_context(arg); if (ctx) { surface = erl_element(2, arg); x = erl_element(3, arg); y = erl_element(4, arg); cairo_set_source_surface(ctx->cr, ptr(surface), val(x), val(y)); erl_free_term(surface); erl_free_term(x); erl_free_term(y); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
response_t set_queue_len(int len, ETERM *tuplep, q_data_t **q_data, thread_data_t *data) { int q_num, cq_idx; ETERM *arg; response_t r; if(erl_size(tuplep) > 2) { arg = erl_element(3, tuplep); q_num = ERL_INT_VALUE(arg); erl_free_term(arg); syslog(LOG_NOTICE,"[%d] q_num: %d, len: %d\n\r", data->idx, q_num, len); if((cq_idx = get_queue_idx(q_num, q_data)) >= 0) { if(nfq_set_queue_maxlen(q_data[cq_idx]->qh, len) >= 0) { r.cs = erl_mk_atom("ok"); r.rsp = erl_mk_atom("ok"); } else { r.cs = erl_mk_atom("error"); r.rsp = erl_mk_estring("failed to set queue max length", strlen("failed to set queue max length")); } } else { r.cs = erl_mk_atom("error"); r.rsp = erl_mk_estring("no such queue", strlen("no such queue")); } } else { r.cs = erl_mk_atom("error"); r.rsp = erl_mk_estring("argument missing", strlen("argument missing")); } return r; }
ETERM *space_delete(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); // remove all subscribers for(erlmunk_subscriber *subscriber = s->subscribers; subscriber != NULL; subscriber = subscriber->hh.next) { space_remove_subscriber(s, subscriber); } // remove all bodies for(erlmunk_body *b = s->bodies; b != NULL; b = b->hh.next) { erlmunk_body_data *data = cpBodyGetUserData(b->body); if (data->term != NULL) erl_free_compound(data->term); free(data); cpSpaceRemoveBody(s->space, b->body); cpBodyDestroy(b->body); cpBodyFree(b->body); space_remove_body_hash(s, b); } return NULL; }
void local_add_watch(ETERM* args) { ETERM *pathp = erl_element(1, args); int pathLength = ERL_BIN_SIZE(pathp); char *path = ERL_BIN_PTR(pathp); ETERM *notifyFilterp = erl_element(2, args); unsigned int notifyFilter_ui = ERL_INT_UVALUE(notifyFilterp); long notifyFilter = (long)notifyFilter_ui; ETERM *watchSubdirsp = erl_element(3, args); int watchSubdirs = ERL_INT_VALUE(watchSubdirsp); int watchID = eNotify_addWatch(path, pathLength, notifyFilter, watchSubdirs); // Prepare response ETERM *tuplep; ETERM *tupleArray[2]; if (watchID < 0) { long errorCode = (long)(-watchID); char errorDesc[1024]; eNotify_getErrorDesc(errorCode, errorDesc, 1024); tupleArray[0] = erl_mk_atom("error"); tupleArray[1] = erl_mk_string(errorDesc); } else if (0 == watchID) { // this may happen if there's a problem converting // a path from utf8 to UTF16 tupleArray[0] = erl_mk_atom("error"); tupleArray[1] = erl_mk_string("internal_error"); } else { tupleArray[0] = erl_mk_atom("ok"); tupleArray[1] = erl_mk_int(watchID); } char buf[1024]; tuplep = erl_mk_tuple(tupleArray, 2); erl_encode(tuplep, buf); write_cmd(buf, erl_term_len(tuplep)); erl_free_array(tupleArray, 2); // free contents from tupleArray }
cairo_context *get_cairo_context(ETERM* arg) { ETERM* ctx = erl_element(1, arg); cairo_context *ret = (cairo_context*)ptr(ctx); erl_free_term(ctx); FILE *f = fopen("/tmp/ec.txt", "a+"); fprintf(f, "Ctx: %p\n", ret); fclose(f); return ret; }
ETERM * set_source_rgba(ETERM* arg, int c_node) { ETERM *r, *g, *b, *a; cairo_context *ctx = get_cairo_context(arg); if (ctx) { r = erl_element(2, arg); g = erl_element(3, arg); b = erl_element(4, arg); a = erl_element(5, arg); cairo_set_source_rgba(ctx->cr, ERL_FLOAT_VALUE(r), val(g), val(b), val(a)); erl_free_term(r); erl_free_term(g); erl_free_term(b); erl_free_term(a); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM *body_activate(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); cpBodyActivate(b->body); return NULL; }
ETERM * surface_create_from_png_stream(ETERM* arg, int c_node) { ETERM* bin = erl_element(1, arg); struct png_data in = {}; in.size = ERL_BIN_SIZE(bin); in.buf = ERL_BIN_PTR(bin); cairo_surface_t *surface = cairo_image_surface_create_from_png_stream(read_cb, &in); erl_free_term(bin); return erl_format("{c_node, ~i, {ok, ~i}}", c_node, surface); }
void handle_connect(ETERM *msg) { ETERM *resp, *tmp; char *host, *db_name, *user, *passwd; int port; tmp = erl_element(2, msg); host = erl_iolist_to_string(tmp); erl_free_term(tmp); tmp = erl_element(3, msg); port = ERL_INT_VALUE(tmp); erl_free_term(tmp); tmp = erl_element(4, msg); db_name = erl_iolist_to_string(tmp); erl_free_term(tmp); tmp = erl_element(5, msg); user = erl_iolist_to_string(tmp); erl_free_term(tmp); tmp = erl_element(6, msg); passwd = erl_iolist_to_string(tmp); erl_free_term(tmp); /* TODO: handle options, passed in next. */ logmsg("INFO: Connecting to %s on %s:%d as %s", db_name, host, port, user); if (mysql_real_connect(&dbh, host, user, passwd, db_name, port, NULL, 0) == NULL) { resp = erl_format("{error, {mysql_error, ~i, ~s}}", mysql_errno(&dbh), mysql_error(&dbh)); write_msg(resp); erl_free_term(resp); exit(2); } resp = erl_format("ok"); write_msg(resp); erl_free_term(resp); }
ETERM *body_update_user_data(ETERM *fromp, ETERM *argp) { // DEBUGF(("body_update_user_data\n")); // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *keyp = erl_element(3, argp); ETERM *valuep = erl_element(4, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; erlmunk_body_data *data = cpBodyGetUserData(b->body); ETERM *new_data_term = erl_lists_keyreplace(data->term, keyp, valuep); erl_free_compound(data->term); data->term = new_data_term; ETERM *new_valuep = erl_proplists_get_value(keyp, new_data_term); // obtain updated key value and return that ETERM *atom_ok = erl_mk_atom("ok"); ETERM **body_update_data_array = (ETERM **) malloc(sizeof(ETERM*) * 2); body_update_data_array[0] = atom_ok; body_update_data_array[1] = new_valuep; ETERM *body_update_data_tuple = erl_mk_tuple(body_update_data_array, 2); free(body_update_data_array); ETERM *reply_tuple = erl_mk_reply(fromp, body_update_data_tuple); ETERM *gen_cast_tuple = erl_mk_gen_cast(reply_tuple); return gen_cast_tuple; }
ETERM *body_get_position(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s = NULL; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; cpVect position = cpBodyGetPosition(b->body); float angle = cpBodyGetAngle(b->body); ETERM **position_tuple_array = (ETERM **) malloc(sizeof(ETERM*) * 2); position_tuple_array[0] = erl_mk_float(position.x); position_tuple_array[1] = erl_mk_float(position.y); ETERM *position_tuple = erl_mk_tuple(position_tuple_array, 2); free(position_tuple_array); ETERM *atom_ok = erl_mk_atom("ok"); ETERM **get_position_array = (ETERM **) malloc(sizeof(ETERM*) * 3); get_position_array[0] = atom_ok; get_position_array[1] = position_tuple; get_position_array[2] = erl_mk_float(angle); ETERM *get_position_tuple = erl_mk_tuple(get_position_array, 3); free(get_position_array); ETERM *reply_tuple = erl_mk_reply(fromp, get_position_tuple); ETERM *gen_cast_tuple = erl_mk_gen_cast(reply_tuple); // DEBUGF(("body_get_position(body: %d, x: %f, y: %f, angle: %f) has succeeded", // body_id, position.x, position.y, angle)); return gen_cast_tuple; }