correct deletion
Some checks failed
Build and Deploy / build-linux (push) Failing after 39s
Build and Deploy / build-windows (CLANG64) (push) Failing after 8m19s
Build and Deploy / package-dist (push) Has been skipped
Build and Deploy / deploy-itch (push) Has been skipped
Build and Deploy / deploy-gitea (push) Has been skipped

This commit is contained in:
2025-02-26 10:07:32 -06:00
parent b23dca6934
commit ad4f3d3f58
4 changed files with 89 additions and 51 deletions

View File

@@ -72,6 +72,18 @@ sdl3_opts.add_cmake_defines({
'CMAKE_BUILD_TYPE': 'Release'
})
chipmunk_opts = cmake.subproject_options()
chipmunk_opts.add_cmake_defines({
'BUILD_DEMOS': 'OFF',
'BUILD_SHARED': 'OFF',
'BUILD_STATIC': 'ON',
'CMAKE_BUILD_TYPE': 'Release',
# uncomment to use floats instead of doubles
# 'CP_USE_DOUBLES': 'OFF',
})
chipmunk_proj = cmake.subproject('chipmunk', options: chipmunk_opts)
deps += chipmunk_proj.dependency('chipmunk_static')
cc = meson.get_compiler('c')
if host_machine.system() == 'darwin'
@@ -131,7 +143,6 @@ deps += dependency('physfs', static:true)
#deps += cc.find_library('opencv')
deps += dependency('threads')
deps += dependency('chipmunk', static:true)
deps += dependency('enet', static:true)
deps += dependency('soloud', static:true)

View File

@@ -3,10 +3,14 @@
#include <chipmunk/chipmunk.h>
#include <chipmunk/chipmunk_unsafe.h>
#include <quickjs.h>
#include <assert.h>
/*
Items are automatically reclaimed when they go out of scope in your quickjs program.
Each chipmunk type's userdata is a pointer to the underlying JSValue it's associated with.
Constraints and shapes are create and forget. They can't be changed between bodies. Just delete and make anew.
Memory for the underlying C types are only freed when the object is out of scope in javascript.
If a body is freed, all of its shapes and constraints are invalid and issue a warning if you try to use them.
*/
#define countof(x) (sizeof(x)/sizeof((x)[0]))
@@ -42,6 +46,9 @@ static void PostBodyFree(cpBody *body, cpSpace *space) {
}
static void ShapeFreeWrap(cpSpace *space, cpShape *shape, void *unused) {
printf("Removing shape %p from space\n", shape);
cpSpace *myspace = cpShapeGetSpace(shape);
printf("i'm currently in %p, removing out of %p\n", myspace, space);
cpSpaceRemoveShape(space, shape);
}
@@ -61,27 +68,39 @@ static void js_cpSpace_finalizer(JSRuntime *rt, JSValue val)
{
printf("freeing space\n");
cpSpace *space = JS_GetOpaque(val, js_cpSpace_class_id);
cpSpaceEachShape(space, PostShapeFree, NULL);
cpSpaceEachConstraint(space, PostConstraintFree, NULL);
cpSpaceEachBody(space, PostBodyFree, NULL);
cpSpaceEachShape(space, PostShapeFree, space);
cpSpaceEachConstraint(space, PostConstraintFree, space);
cpSpaceEachBody(space, PostBodyFree, space);
JSValue *cb = (JSValue*)cpShapeGetUserData(space);
JS_FreeValueRT(rt, *cb);
free(cb);
cpShapeSetUserData(space, NULL); // required to not crash on space free
cpSpaceFree(space);
}
static void body_rm_shape(cpBody *body, cpShape *shape, cpSpace *space)
{
cpSpaceRemoveShape(space, shape);
}
static void body_rm_constraint(cpBody *body, cpConstraint *constraint, cpSpace *space)
{
cpSpaceRemoveConstraint(space, constraint);
}
static void js_cpBody_finalizer(JSRuntime *rt, JSValue val)
{
printf("freeing body\n");
cpBody *body = JS_GetOpaque(val, js_cpBody_class_id);
cpSpace *space = cpBodyGetSpace(body);
if (space)
if (space) {
cpBodyEachShape(body, body_rm_shape, space);
cpBodyEachConstraint(body, PostConstraintFree, space);
cpSpaceRemoveBody(space,body);
cpBodyEachShape(body, PostShapeFree, space);
cpBodyEachConstraint(body, PostConstraintFree, space);
}
JSValue *cb = (JSValue *)cpBodyGetUserData(body);
JS_FreeValueRT(rt, *cb);
@@ -94,7 +113,7 @@ static void js_cpShape_finalizer(JSRuntime *rt, JSValue val)
{
printf("freeing shape\n");
cpShape *shape = JS_GetOpaque(val, js_cpShape_class_id);
cpSpace *space = cpShapeGetSpace(shape);
if (space)
cpSpaceRemoveShape(space, shape);
@@ -205,17 +224,16 @@ static JSValue js_##CP##_get_##ENTRY (JSContext *js, JSValueConst this_val) { \
return TYPE##2js(js, CP##Get##ENTRY(cp)); \
}
// Basic space creation
static JSValue js_make_cpSpace(JSContext *js, JSValueConst this_val, int argc, JSValueConst *argv) {
cpSpace *space = cpSpaceNew();
JSValue obj = JS_NewObjectClass(js, js_cpSpace_class_id);
JS_SetOpaque(obj, space);
// Link the JS object to the Chipmunk space
JSValue *cb = malloc(sizeof(*cb));
*cb = JS_DupValue(js,obj);
*cb = obj;//JS_DupValue(js,obj);
cpSpaceSetUserData(space, cb);
printf("new space is %p\n", space);
return obj;
}
@@ -322,9 +340,9 @@ static JSValue js_cpSpace_add_body (JSContext *js, JSValueConst this_val, int ar
JS_SetOpaque(obj, body);
JSValue *cb = malloc(sizeof(*cb));
*cb = JS_DupValue(js,obj);
*cb = obj;//JS_DupValue(js,obj);
cpBodySetUserData(body, cb);
printf("adding body to space %p\n", space);
cpSpaceAddBody(space, body);
printf("finished adding body at %p\n", body);
return obj;
@@ -464,22 +482,38 @@ static JSValue js_body_each_arbiter(JSContext *js, JSValueConst this_val, int ar
return JS_UNDEFINED;
}
// Shape creation from body
static JSValue js_body_add_circle_shape(JSContext *js, JSValueConst this_val, int argc, JSValueConst *argv) {
cpBody *body = js2cpBody(js, this_val); if (!body) return JS_EXCEPTION;
double radius = js2number(js, argv[0]);
cpVect offset = js2cpvect(js, argv[1]);
cpShape *shape = cpCircleShapeNew(body, (cpFloat)radius, offset);
cpBody *body = js2cpBody(js, this_val);
if (!body) return JS_ThrowReferenceError(js, "Shape must be added to a body.");
cpSpace *space = cpBodyGetSpace(body);
printf("adding circle shape to space %p\n", space);
double radius = 10;
cpVect offset = {0,0};
if (argc > 0 && JS_IsObject(argv[0])) {
JSValue r = JS_GetPropertyStr(js, argv[0], "radius");
if (!JS_IsUndefined(r)) radius = js2number(js, r);
JS_FreeValue(js, r);
printf("RADIUS IS %g\n", radius);
JSValue o = JS_GetPropertyStr(js, argv[0], "offset");
if (!JS_IsUndefined(o)) offset = js2cpvect(js, o);
JS_FreeValue(js, o);
}
cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, offset));
JSValue obj = JS_NewObjectClass(js, js_cpShape_class_id);
JS_SetOpaque(obj, shape);
// Set the circle prototype chain
JS_SetPrototype(js, obj, circle_proto);
JSValue *cb = malloc(sizeof(*cb));
*cb = JS_DupValue(js,obj);
*cb = obj;//JS_DupValue(js,obj);
cpShapeSetUserData(shape, cb);
// We do not call cpSpaceAddShape here. Typically you'd do that explicitly: space.addShape(...)
printf("MADE CIRCLE SHAPE\n");
return obj;
}
@@ -496,7 +530,7 @@ static JSValue js_body_add_segment_shape(JSContext *js, JSValueConst this_val, i
JS_SetPrototype(js, obj, segment_proto);
JSValue *cb = malloc(sizeof(*cb));
*cb = JS_DupValue(js,obj);
*cb = obj;//JS_DupValue(js,obj);
cpShapeSetUserData(shape, cb);
return obj;
@@ -544,9 +578,9 @@ static const JSCFunctionListEntry js_cpBody_funcs[] = {
JS_CFUNC_DEF("eachShape", 1, js_body_each_shape),
JS_CFUNC_DEF("eachConstraint", 1, js_body_each_constraint),
JS_CFUNC_DEF("eachArbiter", 1, js_body_each_arbiter),
JS_CFUNC_DEF("add_circle_shape", 2, js_body_add_circle_shape),
JS_CFUNC_DEF("add_segment_shape", 3, js_body_add_segment_shape),
JS_CFUNC_DEF("add_poly_shape", 1, js_body_add_poly_shape),
JS_CFUNC_DEF("circle", 1, js_body_add_circle_shape),
JS_CFUNC_DEF("segment", 1, js_body_add_segment_shape),
JS_CFUNC_DEF("poly", 1, js_body_add_poly_shape),
};
// Shape-specific get/set
@@ -1222,10 +1256,6 @@ JSValue js_chipmunk2d_use(JSContext *js) {
JSValue export_obj = JS_NewObject(js);
JS_SetPropertyFunctionList(js, export_obj, js_chipmunk2d_funcs, countof(js_chipmunk2d_funcs));
// Add a "Space" constructor
JSValue space_constructor = JS_NewCFunction2(js, js_make_cpSpace, "Space", 0, JS_CFUNC_constructor, 0);
JS_SetPropertyStr(js, export_obj, "Space", space_constructor);
return export_obj;
}

View File

@@ -1,8 +1,5 @@
[wrap-git]
url = https://github.com/johnbrethauer/Chipmunk2D.git
revision = head
url = https://github.com/slembcke/Chipmunk2D.git
revision = Chipmunk-7.0.3
depth = 1
[provide]
chipmunk = chipmunk_dep

View File

@@ -112,7 +112,7 @@ var testCases = [
name: "Body creation and position",
run: () => {
const space = chipmunk.make_space();
const body = space.add_body();
const body = space.body();
body.position = vec(10, 20);
return deepCompare(vec(10, 20), body.position);
}
@@ -121,7 +121,7 @@ var testCases = [
name: "Body mass and moment",
run: () => {
const space = chipmunk.make_space();
const body = space.add_body();
const body = space.body();
body.type = 0
body.mass = 10;
body.moment = 100;
@@ -138,7 +138,7 @@ var testCases = [
name: "Body velocity",
run: () => {
const space = chipmunk.make_space();
const body = space.add_body();
const body = space.body();
body.velocity = vec(5, -5);
return deepCompare(vec(5, -5), body.velocity);
}
@@ -147,7 +147,7 @@ var testCases = [
name: "Body force application",
run: () => {
const space = chipmunk.make_space();
const body = space.add_body();
const body = space.body();
body.type = 0
body.mass = 1;
body.moment = 1
@@ -163,8 +163,8 @@ var testCases = [
name: "Circle shape creation",
run: () => {
const space = chipmunk.make_space();
const body = space.add_body();
const shape = body.add_circle_shape(5, vec(0, 0));
const body = space.body();
const shape = body.circle({radius:5, offset:vec(0, 0)});
const radiusResult = deepCompare(5, shape.radius);
const offsetResult = deepCompare(vec(0, 0), shape.offset);
return {
@@ -177,7 +177,7 @@ var testCases = [
name: "Segment shape creation",
run: () => {
const space = chipmunk.make_space();
const body = space.add_body();
const body = space.body();
const shape = body.add_segment_shape(vec(0, 0), vec(10, 10), 2);
for (var i in shape) console.log(i)
shape.setEndpoints(vec(1, 1), vec(11, 11));
@@ -192,8 +192,8 @@ var testCases = [
name: "Pin joint",
run: () => {
const space = chipmunk.make_space();
const body1 = space.add_body();
const body2 = space.add_body();
const body1 = space.body();
const body2 = space.body();
body1.position = vec(0, 0);
body2.position = vec(10, 0);
const joint = space.pin(body1, body2);
@@ -205,8 +205,8 @@ var testCases = [
name: "Pivot joint",
run: () => {
const space = chipmunk.make_space();
const body1 = space.add_body();
const body2 = space.add_body();
const body1 = space.body();
const body2 = space.body();
const joint = space.pivot(body1, body2, vec(5, 5));
const anchorAResult = deepCompare(vec(5, 5), joint.anchor_a);
const anchorBResult = deepCompare(vec(5, 5), joint.anchor_b);
@@ -225,12 +225,12 @@ var testCases = [
console.log(space.gravity)
space.gravity = vec(0, -9.81);
console.log(space.gravity)
const body = space.add_body();
body.add_circle_shape(5);
const body = space.body();
body.circle(5);
body.mass = 1;
body.moment = 1;
body.position = vec(0, 100);
space.step(1); // 1 second
for (var i = 0; i < 61; i++) space.step(1/60)
const expectedPos = vec(0, 100 - (9.81/2)); // s = ut + (1/2)at^2
return deepCompare(expectedPos, body.position);
}