Fixed object deletion during physics calcs

This commit is contained in:
John Alanbrook 2023-02-28 23:03:28 +00:00
parent f05e0e59f0
commit f5e73b96d3
10 changed files with 83 additions and 99 deletions

View file

@ -608,20 +608,23 @@ void register_collide(void *sym) {
} }
void duk_call_phys_cb(cpArbiter *arb, struct callee c, int hit) void duk_call_phys_cb(cpVect norm, struct callee c, int hit)
{ {
duk_push_heapptr(duk, c.fn); duk_push_heapptr(duk, c.fn);
duk_push_heapptr(duk, c.obj); duk_push_heapptr(duk, c.obj);
int obj = duk_push_object(duk); int obj = duk_push_object(duk);
vect2duk(cpArbiterGetNormal(arb)); vect2duk(norm);
duk_put_prop_literal(duk, obj, "normal"); duk_put_prop_literal(duk, obj, "normal");
duk_push_int(duk, hit); duk_push_int(duk, hit);
duk_put_prop_literal(duk, obj, "hit"); duk_put_prop_literal(duk, obj, "hit");
duk_call_method(duk,1); duk_call_method(duk,1);
// if (duk_pcall_method(duk, 1))
// duk_run_err();
duk_pop(duk); duk_pop(duk);
} }
@ -639,13 +642,27 @@ static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data)
int g1 = cpBodyGetUserData(body1); int g1 = cpBodyGetUserData(body1);
int g2 = cpBodyGetUserData(body2); int g2 = cpBodyGetUserData(body2);
struct gameobject *go = id2go(g1); struct gameobject *go = id2go(g1);
struct gameobject *go2 = id2go(g2);
for (int i = 0; i < arrlen(go->shape_cbs); i++) { cpVect norm1 = cpArbiterGetNormal(arb);
duk_call_phys_cb(arb, go->shape_cbs[i].cbs.begin, g2);
} for (int i = 0; i < arrlen(go->shape_cbs); i++)
duk_call_phys_cb(norm1, go->shape_cbs[i].cbs.begin, g2);
if (go->cbs.begin.obj) if (go->cbs.begin.obj)
duk_call_phys_cb(arb, go->cbs.begin, g2); duk_call_phys_cb(norm1, go->cbs.begin, g2);
return;
cpVect norm2 = norm1;
norm2.x *= -1;
norm2.y *= -1;
for (int i = 0; i < arrlen(go2->shape_cbs); i++)
duk_call_phys_cb(norm2, go2->shape_cbs[i].cbs.begin, g1);
if (go2->cbs.begin.obj)
duk_call_phys_cb(norm2, go2->cbs.begin, g1);
return 1; return 1;
} }

View file

@ -63,5 +63,5 @@ void engine_init()
phys2d_init(); phys2d_init();
YughInfo("Starting sound ..."); YughInfo("Starting sound ...");
//sound_init(); sound_init();
} }

View file

@ -792,6 +792,10 @@ duk_ret_t duk_register(duk_context *duk) {
unregister_obj(obj); unregister_obj(obj);
break; break;
case 5:
unregister_gui(c);
break;
} }
return 0; return 0;

View file

@ -187,24 +187,44 @@ void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
cpShapeFree(shape); cpShapeFree(shape);
} }
/* Really more of a "mark for deletion" ... */ int *go_toclean = NULL;
void gameobject_delete(int id)
{
id2go(id)->next = first;
first = id;
}
/* Free this gameobject */ /* Free this gameobject */
void gameobject_clean(int id) { void gameobject_clean(int id) {
struct gameobject *go = id2go(id); struct gameobject *go = id2go(id);
arrfree(go->shape_cbs);
cpBodyEachShape(go->body, rm_body_shapes, NULL); cpBodyEachShape(go->body, rm_body_shapes, NULL);
cpSpaceRemoveBody(space, go->body); cpSpaceRemoveBody(space, go->body);
cpBodyFree(go->body); cpBodyFree(go->body);
go->body = NULL; go->body = NULL;
} }
/* Really more of a "mark for deletion" ... */
void gameobject_delete(int id)
{
id2go(id)->next = first;
first = id;
if (cpSpaceIsLocked(space)) {
YughInfo("Space is simulating; adding %d to queue ...", id);
arrpush(go_toclean, id);
}
else
gameobject_clean(id);
}
void gameobjects_cleanup() { void gameobjects_cleanup() {
for (int i = 0; i < arrlen(go_toclean); i++) {
YughInfo("Cleaning object %d", go_toclean[i]);
gameobject_clean(go_toclean[i]);
}
arrsetlen(go_toclean, 0);
return;
int clean = first; int clean = first;
YughInfo("Initiating a clean");
while (clean >= 0 && id2go(clean)->body) { while (clean >= 0 && id2go(clean)->body) {
gameobject_clean(clean); gameobject_clean(clean);
@ -212,71 +232,6 @@ void gameobjects_cleanup() {
} }
} }
void gameobject_save(struct gameobject *go, FILE * file)
{
/*
fwrite(go, sizeof(*go), 1, file);
YughInfo("Number of components is %d.", arrlen(go->components));
int n = arrlen(go->components);
fwrite(&n, sizeof(n), 1, file);
for (int i = 0; i < n; i++) {
fwrite(&go->components[i].id, sizeof(int), 1, file);
if (go->components[i].io == NULL)
fwrite(go->components[i].data, go->components[i].datasize, 1, file);
else
go->components[i].io(go->components[i].data, file, 0);
}
*/
}
void gameobject_init(struct gameobject *go, FILE * fprefab)
{
/*
go->body = cpSpaceAddBody(space, cpBodyNew(go->mass, 1.f));
cpBodySetType(go->body, go->bodytype);
cpBodySetUserData(go->body, go);
int comp_n;
fread(&comp_n, sizeof(int), 1, fprefab);
arrfree(go->components);
int n;
for (int i = 0; i < comp_n; i++) {
fread(&n, sizeof(int), 1, fprefab);
arrput(go->components, components[n]);
struct component *newc = &arrlast(go->components);
newc->go = go;
newc->data = newc->make(newc->go);
if (newc->io == NULL)
fread(newc->data, newc->datasize, 1, fprefab);
else
newc->io(newc->data, fprefab, 1);
newc->init(newc->data, go);
}
*/
}
void gameobject_saveprefab(struct gameobject *go)
{
/*
char prefabfname[60] = { '\0' };
strncat(prefabfname, go->editor.prefabName, MAXNAME);
strncat(prefabfname, EXT_PREFAB, 10);
FILE *pfile = fopen(prefabfname, "wb+");
gameobject_save(go, pfile);
fclose(pfile);
findPrefabs();
*/
}
void gameobject_move(struct gameobject *go, cpVect vec) void gameobject_move(struct gameobject *go, cpVect vec)
{ {
cpVect p = cpBodyGetPosition(go->body); cpVect p = cpBodyGetPosition(go->body);

View file

@ -48,15 +48,9 @@ int shape2gameobject(cpShape *shape);
void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go); void go_shape_apply(cpBody *body, cpShape *shape, struct gameobject *go);
void gameobject_save(struct gameobject *go, FILE * file);
void gameobject_saveprefab(struct gameobject *go);
/* Tries a few methods to select a gameobject; if none is selected returns -1 */ /* Tries a few methods to select a gameobject; if none is selected returns -1 */
int pos2gameobject(cpVect pos); int pos2gameobject(cpVect pos);
void gameobject_init(struct gameobject *go, FILE * fprefab);
void gameobject_move(struct gameobject *go, cpVect vec); void gameobject_move(struct gameobject *go, cpVect vec);
void gameobject_rotate(struct gameobject *go, float as); void gameobject_rotate(struct gameobject *go, float as);
void gameobject_setangle(struct gameobject *go, float angle); void gameobject_setangle(struct gameobject *go, float angle);

View file

@ -144,7 +144,6 @@ void call_input_signal(char *signal) {
int len = arrlen(pawns); int len = arrlen(pawns);
void *framepawns[len]; void *framepawns[len];
memcpy(framepawns, pawns, len*sizeof(*pawns)); memcpy(framepawns, pawns, len*sizeof(*pawns));
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
script_eval_w_env(signal, framepawns[i]); script_eval_w_env(signal, framepawns[i]);
} }

View file

@ -16,9 +16,6 @@ void save_level(char name[MAXNAME])
int objs = arrlen(gameobjects); int objs = arrlen(gameobjects);
fwrite(&objs, sizeof(objs), 1, lfile); fwrite(&objs, sizeof(objs), 1, lfile);
for (int i = 0; i < objs; i++)
gameobject_save(&gameobjects[i], lfile);
fclose(lfile); fclose(lfile);
} }

View file

@ -171,6 +171,16 @@ void unregister_obj(void *obj)
if (guis[i].obj == obj) arrdel(nk_guis,i); if (guis[i].obj == obj) arrdel(nk_guis,i);
} }
void unregister_gui(struct callee c)
{
for (int i = arrlen(guis)-1; i >= 0; i--) {
if (guis[i].obj == c.obj && guis[i].fn == c.fn) {
arrdel(guis, i);
return;
}
}
}
void register_update(struct callee c) { void register_update(struct callee c) {
arrput(updates, c); arrput(updates, c);
} }

View file

@ -36,6 +36,7 @@ time_t file_mod_secs(const char *file);
void register_update(struct callee c); void register_update(struct callee c);
void call_updates(double dt); void call_updates(double dt);
void unregister_gui(struct callee c);
void register_gui(struct callee c); void register_gui(struct callee c);
void register_nk_gui(struct callee c); void register_nk_gui(struct callee c);
void call_gui(); void call_gui();

View file

@ -55,6 +55,11 @@ static double framems[FPSBUF];
int framei = 0; int framei = 0;
int fps; int fps;
#define SIM_STOP 0
#define SIM_PLAY 1
#define SIM_PAUSE 2
#define SIM_STEP 3
void seghandle(int sig) { void seghandle(int sig) {
#ifdef __linux__ #ifdef __linux__
void *ents[512]; void *ents[512];
@ -190,7 +195,7 @@ int main(int argc, char **args) {
if (framei == FPSBUF) framei = 0; if (framei == FPSBUF) framei = 0;
if (sim_play) { if (sim_play == SIM_PLAY || sim_play == SIM_STEP) {
timer_update(elapsed); timer_update(elapsed);
physlag += elapsed; physlag += elapsed;
call_updates(elapsed * timescale); call_updates(elapsed * timescale);
@ -199,7 +204,7 @@ int main(int argc, char **args) {
physlag -= physMS; physlag -= physMS;
phys2d_update(physMS * timescale); phys2d_update(physMS * timescale);
call_physics(physMS * timescale); call_physics(physMS * timescale);
if (sim_play == 2) sim_pause(); if (sim_play == SIM_STEP) sim_pause();
} }
} }
@ -227,25 +232,27 @@ int frame_fps()
return FPSBUF / fpsms; return FPSBUF / fpsms;
} }
int sim_playing() { return sim_play; } int sim_playing() { return sim_play == SIM_PLAY; }
int sim_paused() { return (!sim_play && gameobjects_saved()); } int sim_paused() { return sim_play == SIM_PAUSE; }
int sim_stopped() { return sim_play == SIM_STOP; }
void sim_start() { void sim_start() {
sim_play = 1; sim_play = SIM_PLAY;
} }
void sim_pause() { void sim_pause() {
sim_play = 0; sim_play = SIM_PAUSE;
} }
void sim_stop() { void sim_stop() {
/* Revert starting state of everything from sim_start */ /* Revert starting state of everything from sim_start */
sim_play = 0; sim_play = SIM_STOP;
} }
void sim_step() { void sim_step() {
if (sim_paused()) { if (sim_paused()) {
sim_play = 2; YughInfo("Step");
sim_play = SIM_STEP;
} }
} }