kripken / box2d.js

Port of Box2D to JavaScript using Emscripten
1.33k stars 196 forks source link

userData dont work #8

Open Wu-Hao opened 11 years ago

Wu-Hao commented 11 years ago

body.set_userData(x);

it only appears to accept numeric parameters, which is not useful, it should be able to accept js objects

marcwlester commented 11 years ago

as a work around I use body.userData = { ... };

whackashoe commented 8 years ago

What I do is this: I throw the data I need in a dictionary with a integer key, I pass this key into set_userData and then I can look up the corresponding data from the dictionary when I do get_userData.

derek1906 commented 7 years ago

Since userData accepts a void * you will have to allocate some space for your datatype and pass the pointer to set_userData. Here is an example of how you store a string:

// some typedef
var char = "i8";

// Malloc space for input string and returns pointer.
function mallocString(str){
    str = String(str);
    var strptr = Box2D._malloc(str.length + 1, char, Box2D.ALLOC_STACK);
    for(var offset = 0; offset < str.length; offset++){
        Box2D.setValue(strptr + offset, str.charCodeAt(offset), char);
    }
    Box2D.setValue(strptr + offset, 0, char);   // null terminated
    return strptr;
}

// Get string back from a string pointer.
function getString(strptr){
    if(strptr === 0) return "";
    var builder = "", c;
    while(c = Box2D.getValue(strptr++, char)){
        builder += String.fromCharCode(c);
    }
    return builder;
}

// ...

bodyDef.set_userData(mallocString("Hello world"));  // store "Hello world"
var body = world.CreateBody(bodyDef);

getString(body.GetUserData());  // "Hello world"

More on accessing memory can be found here. Remember to free the string after you destroy the body with Box2D._free:

Box2D._free(body.GetUserData());
Box2D.destroy(body);