forked from enlightenment/efl
EPhysics: properly handle world delete
SVN revision: 75140
This commit is contained in:
parent
4d800075e7
commit
0bd1f327a4
|
@ -36,20 +36,23 @@ struct _EPhysics_World {
|
||||||
double last_update;
|
double last_update;
|
||||||
double rate;
|
double rate;
|
||||||
double fixed_time_step;
|
double fixed_time_step;
|
||||||
|
double max_sleeping_time;
|
||||||
Eina_Bool running:1;
|
Eina_Bool running:1;
|
||||||
Eina_Bool active:1;
|
Eina_Bool active:1;
|
||||||
|
Eina_Bool deleted:1;
|
||||||
Eina_Bool outside_autodel:1;
|
Eina_Bool outside_autodel:1;
|
||||||
Eina_Bool outside_top:1;
|
Eina_Bool outside_top:1;
|
||||||
Eina_Bool outside_bottom:1;
|
Eina_Bool outside_bottom:1;
|
||||||
Eina_Bool outside_left:1;
|
Eina_Bool outside_left:1;
|
||||||
Eina_Bool outside_right:1;
|
Eina_Bool outside_right:1;
|
||||||
double max_sleeping_time;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int _ephysics_world_init_count = 0;
|
static int _ephysics_world_init_count = 0;
|
||||||
static int _worlds_running = 0;
|
static int _worlds_running = 0;
|
||||||
static Eina_Inlist *_worlds = NULL;
|
static Eina_Inlist *_worlds = NULL;
|
||||||
|
static Eina_List *_worlds_to_delete = NULL;
|
||||||
static Ecore_Animator *_anim_simulate = NULL;
|
static Ecore_Animator *_anim_simulate = NULL;
|
||||||
|
static int _worlds_walking = 0;
|
||||||
|
|
||||||
struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback
|
struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback
|
||||||
{
|
{
|
||||||
|
@ -124,13 +127,51 @@ _ephysics_world_tick_cb(btDynamicsWorld *dynamics_world, btScalar timeStep)
|
||||||
cb->func(cb->data, world, NULL);
|
cb->func(cb->data, world, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_world_free(EPhysics_World *world)
|
||||||
|
{
|
||||||
|
EPhysics_World_Callback *cb;
|
||||||
|
EPhysics_Body *body;
|
||||||
|
|
||||||
|
_worlds = eina_inlist_remove(_worlds, EINA_INLIST_GET(world));
|
||||||
|
|
||||||
|
while (world->callbacks)
|
||||||
|
{
|
||||||
|
cb = EINA_INLIST_CONTAINER_GET(world->callbacks,
|
||||||
|
EPhysics_World_Callback);
|
||||||
|
world->callbacks = eina_inlist_remove(world->callbacks,
|
||||||
|
world->callbacks);
|
||||||
|
free(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (world->bodies)
|
||||||
|
{
|
||||||
|
body = EINA_INLIST_CONTAINER_GET(world->bodies, EPhysics_Body);
|
||||||
|
world->bodies = eina_inlist_remove(world->bodies, world->bodies);
|
||||||
|
ephysics_orphan_body_del(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
ephysics_camera_del(world->camera);
|
||||||
|
delete world->dynamics_world;
|
||||||
|
delete world->solver;
|
||||||
|
delete world->dispatcher;
|
||||||
|
delete world->collision;
|
||||||
|
delete world->broadphase;
|
||||||
|
|
||||||
|
free(world);
|
||||||
|
INF("World %p deleted.", world);
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_simulate_worlds(void *data)
|
_simulate_worlds(void *data)
|
||||||
{
|
{
|
||||||
Eina_Inlist *lworlds = (Eina_Inlist *) data;
|
Eina_Inlist *lworlds = (Eina_Inlist *) data;
|
||||||
EPhysics_World *world;
|
EPhysics_World *world;
|
||||||
double time_now;
|
double time_now;
|
||||||
|
void *wrld;
|
||||||
|
|
||||||
|
ephysics_init();
|
||||||
|
_worlds_walking++;
|
||||||
EINA_INLIST_FOREACH(lworlds, world)
|
EINA_INLIST_FOREACH(lworlds, world)
|
||||||
{
|
{
|
||||||
double time_now, delta;
|
double time_now, delta;
|
||||||
|
@ -146,6 +187,18 @@ _simulate_worlds(void *data)
|
||||||
world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
|
world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
|
||||||
world->fixed_time_step);
|
world->fixed_time_step);
|
||||||
}
|
}
|
||||||
|
_worlds_walking--;
|
||||||
|
|
||||||
|
if (_worlds_walking > 0)
|
||||||
|
{
|
||||||
|
ephysics_shutdown();
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EINA_LIST_FREE(_worlds_to_delete, wrld)
|
||||||
|
_ephysics_world_free((EPhysics_World *)wrld);
|
||||||
|
|
||||||
|
ephysics_shutdown();
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +300,6 @@ ephysics_world_shutdown(void)
|
||||||
{
|
{
|
||||||
EPhysics_World *world = EINA_INLIST_CONTAINER_GET(
|
EPhysics_World *world = EINA_INLIST_CONTAINER_GET(
|
||||||
_worlds, EPhysics_World);
|
_worlds, EPhysics_World);
|
||||||
_worlds = eina_inlist_remove(_worlds, _worlds);
|
|
||||||
ephysics_world_del(world);
|
ephysics_world_del(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +474,6 @@ EAPI void
|
||||||
ephysics_world_del(EPhysics_World *world)
|
ephysics_world_del(EPhysics_World *world)
|
||||||
{
|
{
|
||||||
EPhysics_World_Callback *cb;
|
EPhysics_World_Callback *cb;
|
||||||
EPhysics_Body *body;
|
|
||||||
|
|
||||||
if (!world)
|
if (!world)
|
||||||
{
|
{
|
||||||
|
@ -430,6 +481,9 @@ ephysics_world_del(EPhysics_World *world)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (world->deleted) return;
|
||||||
|
|
||||||
|
world->deleted = EINA_TRUE;
|
||||||
EINA_INLIST_FOREACH(world->callbacks, cb)
|
EINA_INLIST_FOREACH(world->callbacks, cb)
|
||||||
{
|
{
|
||||||
if (cb->type == EPHYSICS_CALLBACK_WORLD_DEL)
|
if (cb->type == EPHYSICS_CALLBACK_WORLD_DEL)
|
||||||
|
@ -437,33 +491,15 @@ ephysics_world_del(EPhysics_World *world)
|
||||||
}
|
}
|
||||||
|
|
||||||
ephysics_world_running_set(world, EINA_FALSE);
|
ephysics_world_running_set(world, EINA_FALSE);
|
||||||
_worlds = eina_inlist_remove(_worlds, EINA_INLIST_GET(world));
|
|
||||||
|
|
||||||
while (world->callbacks)
|
if (_worlds_walking > 0)
|
||||||
{
|
{
|
||||||
cb = EINA_INLIST_CONTAINER_GET(world->callbacks,
|
_worlds_to_delete = eina_list_append(_worlds_to_delete, world);
|
||||||
EPhysics_World_Callback);
|
INF("World %p marked to delete.", world);
|
||||||
world->callbacks = eina_inlist_remove(world->callbacks,
|
return;
|
||||||
world->callbacks);
|
|
||||||
free(cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (world->bodies)
|
_ephysics_world_free(world);
|
||||||
{
|
|
||||||
body = EINA_INLIST_CONTAINER_GET(world->bodies, EPhysics_Body);
|
|
||||||
world->bodies = eina_inlist_remove(world->bodies, world->bodies);
|
|
||||||
ephysics_orphan_body_del(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
ephysics_camera_del(world->camera);
|
|
||||||
delete world->dynamics_world;
|
|
||||||
delete world->solver;
|
|
||||||
delete world->dispatcher;
|
|
||||||
delete world->collision;
|
|
||||||
delete world->broadphase;
|
|
||||||
|
|
||||||
free(world);
|
|
||||||
INF("World %p deleted.", world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
|
Loading…
Reference in New Issue