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; }
void handle_subscriber(erlmunk_subscriber *subscriber, element *bodies) { element *el; int count = 0; LL_COUNT(bodies, el, count); // DEBUGF(("# bodies in subscriber bounding box: %d", count)); ETERM **l_array = (ETERM **) malloc(sizeof(ETERM) * count); int nth_body = 0; LL_FOREACH(bodies, el) { cpVect vect = cpBodyGetPosition(el->body); float angle = cpBodyGetAngle(el->body); // cpVect vel = cpBodyGetVelocity(el->body); erlmunk_body_data *data = (erlmunk_body_data *) cpBodyGetUserData(el->body); // DEBUGF(("id: %d, x: %f, y: %f, angle: %f, vel.x: %f, vel.y: %f, data: %p", // data->id, vect.x, vect.y, angle, vel.x, vel.y, data)); ETERM **t_array = (ETERM **) malloc(sizeof(ETERM) * 4); t_array[0] = erl_mk_float(vect.x); t_array[1] = erl_mk_float(vect.y); t_array[2] = erl_mk_float(angle); if (data->term == NULL) t_array[3] = erl_mk_undefined(); else t_array[3] = erl_copy_term(data->term); ETERM *tuple = erl_mk_tuple(t_array, 4); free(t_array); ETERM *prop_value = erl_mk_int_prop_value(data->id, tuple); l_array[nth_body++] = prop_value; }
static VALUE erlix_list_head(VALUE self){ ErlixTerm *list; ETERM *ep; Data_Get_Struct(self,ErlixTerm,list); if(ERL_IS_EMPTY_LIST(list->term)){ return Qnil; } ep=erl_hd(list->term); return erlix_term(erl_copy_term(ep)); }
ETERM *space_add_boundaries(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *lower_leftp = erl_element(2, argp); ETERM *lower_rightp = erl_element(3, argp); ETERM *upper_leftp = erl_element(4, argp); ETERM *upper_rightp = erl_element(5, argp); ETERM *collision_categoryp = erl_element(6, argp); ETERM *datap = erl_element(7, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); cpVect lowerLeft = cpv(ERL_FLOAT_VALUE(erl_element(1, lower_leftp)), ERL_FLOAT_VALUE(erl_element(2, lower_leftp))); cpVect lowerRight = cpv(ERL_FLOAT_VALUE(erl_element(1, lower_rightp)), ERL_FLOAT_VALUE(erl_element(2, lower_rightp))); cpVect upperLeft = cpv(ERL_FLOAT_VALUE(erl_element(1, upper_leftp)), ERL_FLOAT_VALUE(erl_element(2, upper_leftp))); cpVect upperRight = cpv(ERL_FLOAT_VALUE(erl_element(1, upper_rightp)), ERL_FLOAT_VALUE(erl_element(2, upper_rightp))); // get the static body that comes with the space cpBody *static_body = cpSpaceGetStaticBody(s->space); erlmunk_body_data *data = malloc(sizeof(erlmunk_body_data)); data->id = BOUNDARY_BODY_ID; data->term = erl_copy_term(datap); cpBodySetUserData(static_body, (cpDataPointer) data); // bottom cpShape *bottomBoundaryShape = cpSegmentShapeNew(static_body, lowerLeft, lowerRight, 0.0f); cpShapeSetCollisionType(bottomBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, bottomBoundaryShape); // top cpShape *topBoundaryShape = cpSegmentShapeNew(static_body, upperLeft, upperRight, 0.0f); cpShapeSetCollisionType(topBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, topBoundaryShape); // left cpShape *leftBoundaryShape = cpSegmentShapeNew(static_body, lowerLeft, upperLeft, 0.0f); cpShapeSetCollisionType(leftBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, leftBoundaryShape); // right cpShape *rightBoundaryShape = cpSegmentShapeNew(static_body, lowerRight, upperRight, 0.0f); cpShapeSetCollisionType(rightBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, rightBoundaryShape); return NULL; }
static VALUE erlix_list_init(VALUE self,VALUE ary){ ErlixTerm *list; ETERM **les; VALUE e; ErlixTerm *ep; int i; Data_Get_Struct(self,ErlixTerm,list); if(NIL_P(ary)){ //empty list list->term=erl_mk_empty_list(); return self; } if(TYPE(ary)==T_ARRAY){ if(RARRAY_LEN(ary)==0){ //empty list list->term=erl_mk_empty_list(); }else{ //check: all elements' must be ErlixTerm or auto-convertable Type for(i=0;i<RARRAY_LEN(ary);i++){ e=RARRAY_PTR(ary)[i]; if(!IS_ETERM(e) && !CAN_AUTO_CONV(e)){ rb_raise(rb_eTypeError,"all list's elements must be ErlixTerm or Auto-Convertable-Type!"); } } les=(ETERM**)malloc(sizeof(ETERM*)*(RARRAY_LEN(ary))); for(i=0;i<RARRAY_LEN(ary);i++){ e=RARRAY_PTR(ary)[i]; if(IS_ETERM(e)){ Data_Get_Struct(e,ErlixTerm,ep); *(les+i)=erl_copy_term(ep->term); }else{ *(les+i)=erlix_auto_conv(e); } } list->term=erl_mk_list(les,RARRAY_LEN(ary)); //for(i=0;i<RARRAY(ary)->len;i++){ // erl_free_term(*(les+i)); //} free(les); } }else if(TYPE(ary)==T_STRING){ list->term=erl_mk_estring(RSTRING_PTR(ary), RSTRING_LEN(ary)); } return self; }
static VALUE erlix_list_init2(int argc, VALUE* argv,VALUE self){ ErlixTerm *list; ETERM **les; VALUE e; ErlixTerm *ep; int i; Data_Get_Struct(self,ErlixTerm,list); if(argc==0){ //empty list list->term=erl_mk_empty_list(); return self; } if(argc==1 && (ARRAY_P(*argv)||STRING_P(*argv))){ return erlix_list_init(self, *argv); } //check: all elements' must be ErlixTerm or auto-convertable Type for(i=0;i<argc;i++){ e=*(argv+i); if(!IS_ETERM(e) && !CAN_AUTO_CONV(e)){ rb_raise(rb_eTypeError,"all list's elements must be ErlixTerm or Auto-Convertable-Type!"); } } les=(ETERM**)malloc(sizeof(ETERM*)*argc); for(i=0;i<argc;i++){ e=*(argv+i); if(IS_ETERM(e)){ Data_Get_Struct(e,ErlixTerm,ep); *(les+i)=erl_copy_term(ep->term); }else{ *(les+i)=erlix_auto_conv(e); } } list->term=erl_mk_list(les,argc); //for(i=0;i<RARRAY(ary)->len;i++){ // erl_free_term(*(les+i)); //} free(les); return self; }
static VALUE erlix_list_cons(VALUE self,VALUE head){ ErlixTerm *list; ETERM *ep; ErlixTerm *hd; VALUE ret; if(!IS_ETERM(head) && !CAN_AUTO_CONV(head)){ rb_raise(rb_eTypeError,"the head must be ErlixTerm or Auto-Convertable-Type!"); return Qnil; } Data_Get_Struct(self,ErlixTerm,list); if(IS_ETERM(head)){ Data_Get_Struct(head,ErlixTerm,hd); ep=erl_cons(hd->term,list->term); }else{ ep=erl_cons(erlix_auto_conv(head),list->term); } ret = erlix_term(erl_copy_term(ep)); erl_free_term(ep); return ret; }
ETERM *body_set_user_data(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *datap = 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; erlmunk_body_data *data = cpBodyGetUserData(b->body); data->term = erl_copy_term(datap); cpBodySetUserData(b->body, (cpDataPointer) data); return NULL; }
static VALUE erlix_list_to_ary(VALUE self){ ErlixTerm *list; ETERM *hd,*tmp,*ep; VALUE ret; int len, i; Data_Get_Struct(self,ErlixTerm,list); len=erl_length(list->term); ret=rb_ary_new2(len); ep=list->term; i=1; while(!ERL_IS_EMPTY_LIST(ep)){ hd=erl_hd(ep); rb_ary_store(ret,i,erlix_term(erl_copy_term(hd))); tmp=erl_tl(ep); //if(ep!=list->term)erl_free_term(ep); ep=tmp; //if(ERL_IS_EMPTY_LIST(ep)){ // erl_free_term(ep); //} ++i; } return ret; }
static VALUE erlix_list_create(int argc,VALUE *argv,VALUE klass){ ETERM *rterm; ETERM **les; ErlixTerm *ep; VALUE e; int i; if(argc==0){ //empty list rterm=erl_mk_empty_list(); }else{ //check: all elements' must be ErlixTerm or auto-convertable Type for(i=0;i<argc;i++){ e=argv[i]; if(!IS_ETERM(e) && !CAN_AUTO_CONV(argv[i])){ rb_raise(rb_eTypeError,"all list's elements must be ErlixTerm or Auto-Convertable-Type!"); } } les=(ETERM**)malloc(sizeof(ETERM*)*argc); for(i=0;i<argc;i++){ e=argv[i]; if(IS_ETERM(e)){ Data_Get_Struct(e,ErlixTerm,ep); *(les+i)=erl_copy_term(ep->term); }else{ *(les+i)=erlix_auto_conv(e); } } rterm=erl_mk_list(les,argc); //for(i=0;i<argc;i++){ // erl_free_term(*(les+i)); //} free(les); } return erlix_term(rterm); }
ETERM *space_subscribe_box(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *subscriber_pidp = erl_element(2, argp); ETERM *bounding_boxp = erl_element(3, argp); ETERM *leftp = erl_element(1, bounding_boxp); ETERM *bottomp = erl_element(2, bounding_boxp); ETERM *rightp = erl_element(3, bounding_boxp); ETERM *topp = erl_element(4, bounding_boxp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); erlmunk_client *client = get_current_client(); space_add_subscriber(s, client, erl_copy_term(subscriber_pidp), ERL_FLOAT_VALUE(leftp), ERL_FLOAT_VALUE(bottomp), ERL_FLOAT_VALUE(rightp), ERL_FLOAT_VALUE(topp)); // DEBUGF(("space_subscribe_box(client fd: %d) has succeeded", // client->fd)); return NULL; }
ETERM *space_subscribe_collision(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *typeap = erl_element(2, argp); ETERM *typebp = erl_element(3, argp); ETERM *pidp = erl_element(4, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); erlmunk_subscriber *subscriber = (erlmunk_subscriber *) malloc(sizeof(erlmunk_subscriber)); subscriber->client = get_current_client(); subscriber->from = erl_copy_term(pidp); cpCollisionHandler *handler = cpSpaceAddCollisionHandler(s->space, ERL_INT_VALUE(typeap), ERL_INT_VALUE(typebp)); handler->beginFunc = handle_collision; handler->userData = subscriber; return NULL; }
/* * FIXME: Deep (the whole tree) or shallow (just the top term) copy? * The documentation never says, but the code as written below will * make a deep copy. This should be documented. */ ETERM *erl_copy_term(const ETERM *ep) { int i; ETERM *cp; if (!ep) return NULL; /* ASSERT(ep != NULL); */ cp = erl_alloc_eterm(ERL_TYPE(ep)); ERL_COUNT(cp) = 1; switch(ERL_TYPE(cp)) { case ERL_INTEGER: case ERL_SMALL_BIG: ERL_INT_VALUE(cp) = ERL_INT_VALUE(ep); break; case ERL_U_INTEGER: case ERL_U_SMALL_BIG: ERL_INT_UVALUE(cp) = ERL_INT_UVALUE(ep); break; case ERL_LONGLONG: ERL_LL_VALUE(cp) = ERL_LL_VALUE(ep); break; case ERL_U_LONGLONG: ERL_LL_UVALUE(cp) = ERL_LL_UVALUE(ep); break; case ERL_FLOAT: ERL_FLOAT_VALUE(cp) = ERL_FLOAT_VALUE(ep); break; case ERL_ATOM: if (!erl_atom_copy(&cp->uval.aval.d, &ep->uval.aval.d)) { erl_free_term(cp); erl_errno = ENOMEM; return NULL; } break; case ERL_PID: /* FIXME: First copy the bit pattern, then duplicate the node name and plug in. Somewhat ugly (also done with port and ref below). */ memcpy(&cp->uval.pidval, &ep->uval.pidval, sizeof(Erl_Pid)); erl_atom_copy(&cp->uval.pidval.node, &ep->uval.pidval.node); ERL_COUNT(cp) = 1; break; case ERL_PORT: memcpy(&cp->uval.portval, &ep->uval.portval, sizeof(Erl_Port)); erl_atom_copy(&cp->uval.portval.node, &ep->uval.portval.node); ERL_COUNT(cp) = 1; break; case ERL_REF: memcpy(&cp->uval.refval, &ep->uval.refval, sizeof(Erl_Ref)); erl_atom_copy(&cp->uval.refval.node, &ep->uval.refval.node); ERL_COUNT(cp) = 1; break; case ERL_LIST: HEAD(cp) = erl_copy_term(HEAD(ep)); TAIL(cp) = erl_copy_term(TAIL(ep)); break; case ERL_EMPTY_LIST: break; case ERL_TUPLE: i = ERL_TUPLE_SIZE(cp) = ERL_TUPLE_SIZE(ep); ERL_TUPLE_ELEMS(cp) = (ETERM**) erl_malloc(i * sizeof(ETERM*)); for(i=0; i < ERL_TUPLE_SIZE(ep); i++) ERL_TUPLE_ELEMENT(cp,i) = erl_copy_term(ERL_TUPLE_ELEMENT(ep, i)); break; case ERL_BINARY: ERL_BIN_SIZE(cp) = ERL_BIN_SIZE(ep); ERL_BIN_PTR(cp) = (unsigned char *) erl_malloc(ERL_BIN_SIZE(ep)); memcpy(ERL_BIN_PTR(cp), ERL_BIN_PTR(ep), ERL_BIN_SIZE(ep)); break; case ERL_FUNCTION: i = ERL_CLOSURE_SIZE(cp) = ERL_CLOSURE_SIZE(ep); ERL_FUN_ARITY(cp) = ERL_FUN_ARITY(ep); ERL_FUN_NEW_INDEX(cp) = ERL_FUN_NEW_INDEX(ep); ERL_FUN_INDEX(cp) = erl_copy_term(ERL_FUN_INDEX(ep)); ERL_FUN_UNIQ(cp) = erl_copy_term(ERL_FUN_UNIQ(ep)); ERL_FUN_CREATOR(cp) = erl_copy_term(ERL_FUN_CREATOR(ep)); ERL_FUN_MODULE(cp) = erl_copy_term(ERL_FUN_MODULE(ep)); memcpy(ERL_FUN_MD5(cp), ERL_FUN_MD5(ep), sizeof(ERL_FUN_MD5(ep))); ERL_CLOSURE(cp) = (ETERM**) erl_malloc(i * sizeof(ETERM*)); for(i=0; i < ERL_CLOSURE_SIZE(ep); i++) ERL_CLOSURE_ELEMENT(cp,i) = erl_copy_term(ERL_CLOSURE_ELEMENT(ep, i)); break; default: erl_err_msg("<ERROR> erl_copy_term: wrong type encountered !"); erl_free_term(cp); return (ETERM *) NULL; } return cp; }
int main(void) #endif { ei_x_buff eix; int index = 0; ETERM **etermpp = NULL, *etermp = NULL; char *charp = NULL; unsigned char uchar, **ucharpp = NULL, *ucharp = NULL; void *voidp = NULL; Erl_Heap *erl_heapp = NULL; int intx = 0; int *intp = NULL; unsigned int uintx, *uintp; unsigned long *ulongp = NULL; long longx = 0; double doublex = 0.0; short shortx = 42; FILE *filep = NULL; Erl_IpAddr erl_ipaddr = NULL; ErlMessage *erlmessagep = NULL; ErlConnect *erlconnectp = NULL; struct hostent *hostp = NULL; struct in_addr *inaddrp = NULL; /* Converion to erl_interface format is in liberl_interface */ intx = erl_errno; ei_encode_term(charp, &index, voidp); ei_x_encode_term(&eix, voidp); ei_decode_term(charp, &index, voidp); erl_init(voidp, longx); erl_connect_init(intx, charp,shortx); erl_connect_xinit(charp,charp,charp,erl_ipaddr,charp,shortx); erl_connect(charp); erl_xconnect(erl_ipaddr,charp); erl_close_connection(intx); erl_receive(intx, ucharp, intx); erl_receive_msg(intx, ucharp, intx, erlmessagep); erl_xreceive_msg(intx, ucharpp, intp, erlmessagep); erl_send(intx, etermp, etermp); erl_reg_send(intx, charp, etermp); erl_rpc(intx,charp,charp,etermp); erl_rpc_to(intx,charp,charp,etermp); erl_rpc_from(intx,intx,erlmessagep); erl_publish(intx); erl_accept(intx,erlconnectp); erl_thiscookie(); erl_thisnodename(); erl_thishostname(); erl_thisalivename(); erl_thiscreation(); erl_unpublish(charp); erl_err_msg(charp); erl_err_quit(charp); erl_err_ret(charp); erl_err_sys(charp); erl_cons(etermp,etermp); erl_copy_term(etermp); erl_element(intx,etermp); erl_hd(etermp); erl_iolist_to_binary(etermp); erl_iolist_to_string(etermp); erl_iolist_length(etermp); erl_length(etermp); erl_mk_atom(charp); erl_mk_binary(charp,intx); erl_mk_empty_list(); erl_mk_estring(charp, intx); erl_mk_float(doublex); erl_mk_int(intx); erl_mk_list(etermpp,intx); erl_mk_pid(charp,uintx,uintx,uchar); erl_mk_port(charp,uintx,uchar); erl_mk_ref(charp,uintx,uchar); erl_mk_long_ref(charp,uintx,uintx,uintx,uchar); erl_mk_string(charp); erl_mk_tuple(etermpp,intx); erl_mk_uint(uintx); erl_mk_var(charp); erl_print_term(filep,etermp); /* erl_sprint_term(charp,etermp); */ erl_size(etermp); erl_tl(etermp); erl_var_content(etermp, charp); erl_format(charp); erl_match(etermp, etermp); erl_global_names(intx, intp); erl_global_register(intx, charp, etermp); erl_global_unregister(intx, charp); erl_global_whereis(intx, charp, charp); erl_init_malloc(erl_heapp,longx); erl_alloc_eterm(uchar); erl_eterm_release(); erl_eterm_statistics(ulongp,ulongp); erl_free_array(etermpp,intx); erl_free_term(etermp); erl_free_compound(etermp); erl_malloc(longx); erl_free(voidp); erl_compare_ext(ucharp, ucharp); erl_decode(ucharp); erl_decode_buf(ucharpp); erl_encode(etermp,ucharp); erl_encode_buf(etermp,ucharpp); erl_ext_size(ucharp); erl_ext_type(ucharp); erl_peek_ext(ucharp,intx); erl_term_len(etermp); erl_gethostbyname(charp); erl_gethostbyaddr(charp, intx, intx); erl_gethostbyname_r(charp, hostp, charp, intx, intp); erl_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp); erl_init_resolve(); erl_distversion(intx); erl_epmd_connect(inaddrp); erl_epmd_port(inaddrp, charp, intp); charp = ERL_ATOM_PTR(etermp); intx = ERL_ATOM_SIZE(etermp); ucharp = ERL_BIN_PTR(etermp); intx = ERL_BIN_SIZE(etermp); etermp = ERL_CONS_HEAD(etermp); etermp = ERL_CONS_TAIL(etermp); intx = ERL_COUNT(etermp); doublex= ERL_FLOAT_VALUE(etermp); uintx = ERL_INT_UVALUE(etermp); intx = ERL_INT_VALUE(etermp); intx = ERL_IS_ATOM(etermp); intx = ERL_IS_BINARY(etermp); intx = ERL_IS_CONS(etermp); intx = ERL_IS_EMPTY_LIST(etermp); intx = ERL_IS_FLOAT(etermp); intx = ERL_IS_INTEGER(etermp); intx = ERL_IS_LIST(etermp); intx = ERL_IS_PID(etermp); intx = ERL_IS_PORT(etermp); intx = ERL_IS_REF(etermp); intx = ERL_IS_TUPLE(etermp); intx = ERL_IS_UNSIGNED_INTEGER(etermp); uchar = ERL_PID_CREATION(etermp); charp = ERL_PID_NODE(etermp); uintx = ERL_PID_NUMBER(etermp); uintx = ERL_PID_SERIAL(etermp); uchar = ERL_PORT_CREATION(etermp); charp = ERL_PORT_NODE(etermp); uintx = ERL_PORT_NUMBER(etermp); uchar = ERL_REF_CREATION(etermp); intx = ERL_REF_LEN(etermp); charp = ERL_REF_NODE(etermp); uintx = ERL_REF_NUMBER(etermp); uintp = ERL_REF_NUMBERS(etermp); etermp = ERL_TUPLE_ELEMENT(etermp,intx); intx = ERL_TUPLE_SIZE(etermp); return BUFSIZ + EAGAIN + EHOSTUNREACH + EINVAL + EIO + EMSGSIZE + ENOMEM + ERL_ATOM + ERL_BINARY + ERL_ERROR + ERL_EXIT + ERL_FLOAT + ERL_INTEGER + ERL_LINK + ERL_LIST + ERL_MSG + ERL_NO_TIMEOUT + ERL_PID + ERL_PORT + ERL_REF + ERL_REG_SEND + ERL_SEND + ERL_SMALL_BIG + ERL_TICK + ERL_TIMEOUT + ERL_TUPLE + ERL_UNLINK + ERL_U_INTEGER + ERL_U_SMALL_BIG + ERL_VARIABLE + ETIMEDOUT + MAXNODELEN + MAXREGLEN; }