attempt at handling automatic removal on destroy
Some checks failed
Build and Deploy / build-linux (push) Failing after 1m17s
Build and Deploy / build-windows (CLANG64) (push) Successful in 9m50s
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
Some checks failed
Build and Deploy / build-linux (push) Failing after 1m17s
Build and Deploy / build-windows (CLANG64) (push) Successful in 9m50s
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:
@@ -28,31 +28,115 @@ static JSValue js_groove;
|
||||
static JSValue js_slide;
|
||||
static JSValue js_ratchet;
|
||||
|
||||
static JSClassID js_cpSpace_class_id;
|
||||
static JSClassID js_cpBody_class_id;
|
||||
static JSClassID js_cpShape_class_id;
|
||||
static JSClassID js_cpConstraint_class_id;
|
||||
|
||||
static void BodyFreeWrap(cpSpace *space, cpBody *body, void *unused) {
|
||||
cpSpaceRemoveBody(space, body);
|
||||
}
|
||||
|
||||
static void PostBodyFree(cpBody *body, cpSpace *space) {
|
||||
cpSpaceAddPostStepCallback(space, BodyFreeWrap, body, NULL);
|
||||
}
|
||||
|
||||
static void ShapeFreeWrap(cpSpace *space, cpShape *shape, void *unused) {
|
||||
cpSpaceRemoveShape(space, shape);
|
||||
}
|
||||
|
||||
static void PostShapeFree(cpShape *shape, cpSpace *space) {
|
||||
cpSpaceAddPostStepCallback(space, ShapeFreeWrap, shape, NULL);
|
||||
}
|
||||
|
||||
static void ConstraintFreeWrap(cpSpace *space, cpConstraint *constraint, void *unused) {
|
||||
cpSpaceRemoveConstraint(space, constraint);
|
||||
}
|
||||
|
||||
static void PostConstraintFree(cpConstraint *constraint, cpSpace *space) {
|
||||
cpSpaceAddPostStepCallback(space, ConstraintFreeWrap, constraint, NULL);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
JSValue *cb = (JSValue*)cpShapeGetUserData(space);
|
||||
JS_FreeValueRT(rt, *cb);
|
||||
free(cb);
|
||||
cpSpaceFree(space);
|
||||
}
|
||||
|
||||
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)
|
||||
cpSpaceRemoveBody(space,body);
|
||||
|
||||
cpBodyEachShape(body, PostShapeFree, space);
|
||||
cpBodyEachConstraint(body, PostConstraintFree, space);
|
||||
|
||||
JSValue *cb = (JSValue *)cpBodyGetUserData(body);
|
||||
JS_FreeValueRT(rt, *cb);
|
||||
free(cb);
|
||||
|
||||
cpBodyFree(body);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
JSValue *cb = (JSValue*)cpShapeGetUserData(shape);
|
||||
JS_FreeValueRT(rt, *cb);
|
||||
free(cb);
|
||||
|
||||
cpShapeFree(shape);
|
||||
}
|
||||
|
||||
static void js_cpConstraint_finalizer(JSRuntime *rt, JSValue val)
|
||||
{
|
||||
printf("freeing constraint\n");
|
||||
cpConstraint *joint = JS_GetOpaque(val, js_cpConstraint_class_id);
|
||||
|
||||
cpSpace *space = cpConstraintGetSpace(joint);
|
||||
if (space)
|
||||
cpSpaceRemoveConstraint(space,joint);
|
||||
|
||||
JSValue *cb = (JSValue*)cpConstraintGetUserData(joint);
|
||||
JS_FreeValueRT(rt, *cb);
|
||||
free(cb);
|
||||
|
||||
cpConstraintFree(joint);
|
||||
}
|
||||
|
||||
#define CPCLASS(TYPE) \
|
||||
static JSClassID js_##TYPE##_class_id; \
|
||||
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val) { \
|
||||
TYPE *cp = JS_GetOpaque(val, js_##TYPE##_class_id); \
|
||||
if(cp) { \
|
||||
/* Free the stored JSValue pointer (user data). */ \
|
||||
JSValue* cb = (JSValue*)TYPE##GetUserData(cp); \
|
||||
if (cb) { \
|
||||
JS_FreeValueRT(rt, *cb); \
|
||||
free(cb); \
|
||||
} \
|
||||
/* Then free/destroy the Chipmunk object if needed. */ \
|
||||
/* For shapes, bodies, constraints, the destroy call is done externally if needed. */ \
|
||||
} \
|
||||
} \
|
||||
static inline TYPE *js2##TYPE(JSContext *js, JSValue v) { \
|
||||
return JS_GetOpaque(v, js_##TYPE##_class_id); \
|
||||
} \
|
||||
static inline JSValue TYPE##2js(JSContext *js, TYPE *cp) { \
|
||||
/* Return the already-associated JSValue. */ \
|
||||
return JS_DupValue(js, *(JSValue*)TYPE##GetUserData(cp)); \
|
||||
} \
|
||||
static inline void js_##TYPE##_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { \
|
||||
TYPE *cp = JS_GetOpaque(val, js_##TYPE##_class_id); \
|
||||
JS_MarkValue(rt, *(JSValue*)TYPE##GetUserData(cp), mark_func); \
|
||||
} \
|
||||
static JSClassDef js_##TYPE##_class = { \
|
||||
#TYPE, \
|
||||
.finalizer = js_##TYPE##_finalizer \
|
||||
.finalizer = js_##TYPE##_finalizer, \
|
||||
.gc_mark = js_##TYPE##_mark, \
|
||||
}; \
|
||||
|
||||
CPCLASS(cpShape)
|
||||
@@ -60,8 +144,6 @@ CPCLASS(cpSpace)
|
||||
CPCLASS(cpBody)
|
||||
CPCLASS(cpConstraint)
|
||||
|
||||
// Helper conversions
|
||||
|
||||
static inline cpVect js2cpvect(JSContext *js, JSValue v) {
|
||||
cpVect ret;
|
||||
JSValue x = JS_GetPropertyStr(js, v, "x");
|
||||
@@ -132,7 +214,7 @@ static JSValue js_make_cpSpace(JSContext *js, JSValueConst this_val, int argc, J
|
||||
|
||||
// Link the JS object to the Chipmunk space
|
||||
JSValue *cb = malloc(sizeof(*cb));
|
||||
*cb = obj;
|
||||
*cb = JS_DupValue(js,obj);
|
||||
cpSpaceSetUserData(space, cb);
|
||||
|
||||
return obj;
|
||||
@@ -231,23 +313,20 @@ static JSValue js_space_step (JSContext *js, JSValueConst this_val, int argc, JS
|
||||
|
||||
static JSValue js_cpSpace_add_body (JSContext *js, JSValueConst this_val, int argc, JSValue *argv) {
|
||||
cpSpace *space = js2cpSpace(js, this_val);
|
||||
if (!space) return JS_EXCEPTION;
|
||||
if (!space) return JS_ThrowReferenceError(js, "Not a space.");
|
||||
|
||||
// Create a dynamic body (so mass, moment, etc. are settable).
|
||||
cpBody *body = cpBodyNew(0, 0);
|
||||
cpBody *body = cpBodyNew(1,1);
|
||||
cpBodySetType(body, CP_BODY_TYPE_DYNAMIC);
|
||||
|
||||
// Make a JS object for the body
|
||||
JSValue obj = JS_NewObjectClass(js, js_cpBody_class_id);
|
||||
JS_SetOpaque(obj, body);
|
||||
|
||||
// Store backref
|
||||
JSValue *cb = malloc(sizeof(*cb));
|
||||
*cb = obj;
|
||||
*cb = JS_DupValue(js,obj);
|
||||
cpBodySetUserData(body, cb);
|
||||
|
||||
// Add to space
|
||||
cpSpaceAddBody(space, body);
|
||||
printf("finished adding body at %p\n", body);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -398,7 +477,7 @@ static JSValue js_body_add_circle_shape(JSContext *js, JSValueConst this_val, in
|
||||
JS_SetPrototype(js, obj, circle_proto);
|
||||
|
||||
JSValue *cb = malloc(sizeof(*cb));
|
||||
*cb = obj;
|
||||
*cb = JS_DupValue(js,obj);
|
||||
cpShapeSetUserData(shape, cb);
|
||||
// We do not call cpSpaceAddShape here. Typically you'd do that explicitly: space.addShape(...)
|
||||
|
||||
@@ -417,7 +496,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 = obj;
|
||||
*cb = JS_DupValue(js,obj);
|
||||
cpShapeSetUserData(shape, cb);
|
||||
|
||||
return obj;
|
||||
@@ -436,7 +515,7 @@ static JSValue js_body_add_poly_shape(JSContext *js, JSValueConst this_val, int
|
||||
JS_SetPrototype(js, obj, poly_proto);
|
||||
|
||||
JSValue *cb = malloc(sizeof(*cb));
|
||||
*cb = obj;
|
||||
*cb = JS_DupValue(js,obj);
|
||||
cpShapeSetUserData(shape, cb);
|
||||
|
||||
return obj;
|
||||
@@ -702,7 +781,7 @@ static JSValue prep_constraint(JSContext *js, cpConstraint *c)
|
||||
|
||||
// Allocate space for the back-reference
|
||||
JSValue *cb = malloc(sizeof(JSValue));
|
||||
*cb = ret;
|
||||
*cb = JS_DupValue(js,ret);
|
||||
cpConstraintSetUserData(c, cb);
|
||||
|
||||
return ret;
|
||||
@@ -980,7 +1059,7 @@ static JSValue js_joint_motor (JSContext *js, JSValueConst this_val, int argc, J
|
||||
|
||||
// Space methods
|
||||
static const JSCFunctionListEntry js_cpSpace_funcs[] = {
|
||||
JS_CFUNC_DEF("add_body", 0, js_cpSpace_add_body),
|
||||
JS_CFUNC_DEF("body", 0, js_cpSpace_add_body),
|
||||
JS_CFUNC_DEF("step", 1, js_space_step),
|
||||
JS_CGETSET_DEF("gravity", js_cpSpace_get_Gravity, js_cpSpace_set_Gravity),
|
||||
JS_CGETSET_DEF("iterations", js_cpSpace_get_Iterations, js_cpSpace_set_Iterations),
|
||||
|
||||
Reference in New Issue
Block a user