double last_update;
double rate;
double fixed_time_step;
+ double max_sleeping_time;
Eina_Bool running:1;
Eina_Bool active:1;
+ Eina_Bool deleted:1;
Eina_Bool outside_autodel:1;
Eina_Bool outside_top:1;
Eina_Bool outside_bottom:1;
Eina_Bool outside_left:1;
Eina_Bool outside_right:1;
- double max_sleeping_time;
};
static int _ephysics_world_init_count = 0;
static int _worlds_running = 0;
static Eina_Inlist *_worlds = NULL;
+static Eina_List *_worlds_to_delete = NULL;
static Ecore_Animator *_anim_simulate = NULL;
+static int _worlds_walking = 0;
struct _ephysics_world_ovelap_filter_cb : public btOverlapFilterCallback
{
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
_simulate_worlds(void *data)
{
Eina_Inlist *lworlds = (Eina_Inlist *) data;
EPhysics_World *world;
double time_now;
+ void *wrld;
+ ephysics_init();
+ _worlds_walking++;
EINA_INLIST_FOREACH(lworlds, world)
{
double time_now, delta;
world->dynamics_world->stepSimulation(delta, world->max_sub_steps,
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;
}
{
EPhysics_World *world = EINA_INLIST_CONTAINER_GET(
_worlds, EPhysics_World);
- _worlds = eina_inlist_remove(_worlds, _worlds);
ephysics_world_del(world);
}
ephysics_world_del(EPhysics_World *world)
{
EPhysics_World_Callback *cb;
- EPhysics_Body *body;
if (!world)
{
return;
}
+ if (world->deleted) return;
+
+ world->deleted = EINA_TRUE;
EINA_INLIST_FOREACH(world->callbacks, cb)
{
if (cb->type == EPHYSICS_CALLBACK_WORLD_DEL)
}
ephysics_world_running_set(world, EINA_FALSE);
- _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)
+ if (_worlds_walking > 0)
{
- body = EINA_INLIST_CONTAINER_GET(world->bodies, EPhysics_Body);
- world->bodies = eina_inlist_remove(world->bodies, world->bodies);
- ephysics_orphan_body_del(body);
+ _worlds_to_delete = eina_list_append(_worlds_to_delete, world);
+ INF("World %p marked to delete.", world);
+ return;
}
- 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);
+ _ephysics_world_free(world);
}
EAPI void