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.obj);
int obj = duk_push_object(duk);
vect2duk(cpArbiterGetNormal(arb));
vect2duk(norm);
duk_put_prop_literal(duk, obj, "normal");
duk_push_int(duk, 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);
}
@ -639,13 +642,27 @@ static cpBool script_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data)
int g1 = cpBodyGetUserData(body1);
int g2 = cpBodyGetUserData(body2);
struct gameobject *go = id2go(g1);
struct gameobject *go2 = id2go(g2);
for (int i = 0; i < arrlen(go->shape_cbs); i++) {
duk_call_phys_cb(arb, go->shape_cbs[i].cbs.begin, g2);
}
cpVect norm1 = cpArbiterGetNormal(arb);
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)
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;
}

View file

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

View file

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

View file

@ -187,24 +187,44 @@ void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
cpShapeFree(shape);
}
/* Really more of a "mark for deletion" ... */
void gameobject_delete(int id)
{
id2go(id)->next = first;
first = id;
}
int *go_toclean = NULL;
/* Free this gameobject */
void gameobject_clean(int id) {
struct gameobject *go = id2go(id);
arrfree(go->shape_cbs);
cpBodyEachShape(go->body, rm_body_shapes, NULL);
cpSpaceRemoveBody(space, go->body);
cpBodyFree(go->body);
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() {
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;
YughInfo("Initiating a clean");
while (clean >= 0 && id2go(clean)->body) {
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)
{
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 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 */
int pos2gameobject(cpVect pos);
void gameobject_init(struct gameobject *go, FILE * fprefab);
void gameobject_move(struct gameobject *go, cpVect vec);
void gameobject_rotate(struct gameobject *go, float as);
void gameobject_setangle(struct gameobject *go, float angle);

View file

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

View file

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

View file

@ -171,6 +171,16 @@ void unregister_obj(void *obj)
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) {
arrput(updates, c);
}

View file

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

View file

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