forked from enlightenment/efl
EPhysics: improving body's event callbacks management
SVN revision: 75144
This commit is contained in:
parent
73e77dff26
commit
cf6678bbd4
|
@ -17,6 +17,7 @@ struct _EPhysics_Body_Callback {
|
||||||
void (*func) (void *data, EPhysics_Body *body, void *event_info);
|
void (*func) (void *data, EPhysics_Body *body, void *event_info);
|
||||||
void *data;
|
void *data;
|
||||||
EPhysics_Callback_Body_Type type;
|
EPhysics_Callback_Body_Type type;
|
||||||
|
Eina_Bool deleted:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EPhysics_Body_Collision {
|
struct _EPhysics_Body_Collision {
|
||||||
|
@ -25,6 +26,55 @@ struct _EPhysics_Body_Collision {
|
||||||
Evas_Coord y;
|
Evas_Coord y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ephysics_body_event_callback_del(EPhysics_Body *body, EPhysics_Body_Callback *cb)
|
||||||
|
{
|
||||||
|
if (cb->deleted) return;
|
||||||
|
|
||||||
|
cb->deleted = EINA_TRUE;
|
||||||
|
|
||||||
|
if (body->walking)
|
||||||
|
{
|
||||||
|
body->to_delete = eina_list_append(body->to_delete, cb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
body->callbacks = eina_inlist_remove(body->callbacks, EINA_INLIST_GET(cb));
|
||||||
|
free(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ephysics_body_event_callback_call(EPhysics_Body *body, EPhysics_Callback_Body_Type type, void *event_info)
|
||||||
|
{
|
||||||
|
Eina_Bool called = EINA_FALSE;
|
||||||
|
EPhysics_Body_Callback *cb;
|
||||||
|
void *clb;
|
||||||
|
|
||||||
|
body->walking++;
|
||||||
|
EINA_INLIST_FOREACH(body->callbacks, cb)
|
||||||
|
{
|
||||||
|
if ((cb->type == type) && (!cb->deleted))
|
||||||
|
{
|
||||||
|
cb->func(cb->data, body, event_info);
|
||||||
|
called = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body->walking--;
|
||||||
|
|
||||||
|
if (body->walking > 0) return called;
|
||||||
|
|
||||||
|
EINA_LIST_FREE(body->to_delete, clb)
|
||||||
|
{
|
||||||
|
cb = (EPhysics_Body_Callback *) clb;
|
||||||
|
body->callbacks = eina_inlist_remove(body->callbacks,
|
||||||
|
EINA_INLIST_GET(cb));
|
||||||
|
free(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return called;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active)
|
ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active)
|
||||||
{
|
{
|
||||||
|
@ -34,9 +84,8 @@ ephysics_body_active_set(EPhysics_Body *body, Eina_Bool active)
|
||||||
body->active = !!active;
|
body->active = !!active;
|
||||||
if (active) return;
|
if (active) return;
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
_ephysics_body_event_callback_call(body, EPHYSICS_CALLBACK_BODY_STOPPED,
|
||||||
if (cb->type == EPHYSICS_CALLBACK_BODY_STOPPED)
|
(void *) body->evas_obj);
|
||||||
cb->func(cb->data, body, (void *) body->evas_obj);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
|
@ -298,18 +347,12 @@ void
|
||||||
ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
||||||
{
|
{
|
||||||
Eina_Bool callback_called = EINA_FALSE;
|
Eina_Bool callback_called = EINA_FALSE;
|
||||||
EPhysics_Body_Callback *cb;
|
|
||||||
|
|
||||||
if (!body)
|
if (!body)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
callback_called = _ephysics_body_event_callback_call(
|
||||||
{
|
body, EPHYSICS_CALLBACK_BODY_UPDATE, (void *) body->evas_obj);
|
||||||
if (cb->type == EPHYSICS_CALLBACK_BODY_UPDATE) {
|
|
||||||
cb->func(cb->data, body, (void *) body->evas_obj);
|
|
||||||
callback_called = EINA_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!callback_called)
|
if (!callback_called)
|
||||||
_ephysics_body_evas_object_default_update(body);
|
_ephysics_body_evas_object_default_update(body);
|
||||||
|
@ -318,20 +361,6 @@ ephysics_body_evas_object_update_select(EPhysics_Body *body)
|
||||||
_ephysics_body_outside_render_area_check(body);
|
_ephysics_body_outside_render_area_check(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_ephysics_body_collision_set(EPhysics_Body_Collision *collision, EPhysics_Body *contact_body, btVector3 position)
|
|
||||||
{
|
|
||||||
double rate;
|
|
||||||
int wy, wh;
|
|
||||||
EPhysics_World *world = contact_body->world;
|
|
||||||
|
|
||||||
ephysics_world_render_geometry_get(world, NULL, &wy, NULL, &wh);
|
|
||||||
rate = ephysics_world_rate_get(world);
|
|
||||||
collision->contact_body = contact_body;
|
|
||||||
collision->x = position.getX() * rate;
|
|
||||||
collision->y = wh + wy - (position.getY() * rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
ephysics_body_collision_position_get(const EPhysics_Body_Collision *collision, Evas_Coord *x, Evas_Coord *y)
|
ephysics_body_collision_position_get(const EPhysics_Body_Collision *collision, Evas_Coord *x, Evas_Coord *y)
|
||||||
{
|
{
|
||||||
|
@ -360,31 +389,36 @@ ephysics_body_collision_contact_body_get(const EPhysics_Body_Collision *collisio
|
||||||
void
|
void
|
||||||
ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body, btVector3 position)
|
ephysics_body_contact_processed(EPhysics_Body *body, EPhysics_Body *contact_body, btVector3 position)
|
||||||
{
|
{
|
||||||
|
EPhysics_Body_Collision *collision;
|
||||||
EPhysics_Body_Callback *cb;
|
EPhysics_Body_Callback *cb;
|
||||||
|
EPhysics_World *world;;
|
||||||
|
double rate;
|
||||||
|
int wy, wh;
|
||||||
|
|
||||||
if ((!body) || (!contact_body))
|
if ((!body) || (!contact_body))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
collision = (EPhysics_Body_Collision *)malloc(
|
||||||
|
sizeof(EPhysics_Body_Collision));
|
||||||
|
|
||||||
|
if (!collision)
|
||||||
{
|
{
|
||||||
if (cb->type == EPHYSICS_CALLBACK_BODY_COLLISION)
|
ERR("Can't allocate collision data structure.");
|
||||||
{
|
return;
|
||||||
EPhysics_Body_Collision *collision;
|
|
||||||
|
|
||||||
collision = (EPhysics_Body_Collision *)malloc(
|
|
||||||
sizeof(EPhysics_Body_Collision));
|
|
||||||
|
|
||||||
if (!collision)
|
|
||||||
{
|
|
||||||
ERR("Can't allocate collision data structure.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ephysics_body_collision_set(collision, contact_body, position);
|
|
||||||
cb->func(cb->data, body, collision);
|
|
||||||
free(collision);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
world = contact_body->world;
|
||||||
|
ephysics_world_render_geometry_get(world, NULL, &wy, NULL, &wh);
|
||||||
|
rate = ephysics_world_rate_get(world);
|
||||||
|
|
||||||
|
collision->contact_body = contact_body;
|
||||||
|
collision->x = position.getX() * rate;
|
||||||
|
collision->y = wh + wy - (position.getY() * rate);
|
||||||
|
|
||||||
|
_ephysics_body_event_callback_call(body, EPHYSICS_CALLBACK_BODY_COLLISION,
|
||||||
|
(void *) collision);
|
||||||
|
|
||||||
|
free(collision);
|
||||||
}
|
}
|
||||||
|
|
||||||
btRigidBody *
|
btRigidBody *
|
||||||
|
@ -549,12 +583,7 @@ ephysics_orphan_body_del(EPhysics_Body *body)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Callback *cb;
|
EPhysics_Body_Callback *cb;
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
_ephysics_body_event_callback_call(body, EPHYSICS_CALLBACK_BODY_DEL, NULL);
|
||||||
{
|
|
||||||
if (cb->type == EPHYSICS_CALLBACK_BODY_DEL)
|
|
||||||
cb->func(cb->data, body, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ephysics_body_del(body);
|
_ephysics_body_del(body);
|
||||||
INF("Body %p deleted.", body);
|
INF("Body %p deleted.", body);
|
||||||
}
|
}
|
||||||
|
@ -900,7 +929,7 @@ EAPI void *
|
||||||
ephysics_body_event_callback_del(EPhysics_Body *body, EPhysics_Callback_Body_Type type, EPhysics_Body_Event_Cb func)
|
ephysics_body_event_callback_del(EPhysics_Body *body, EPhysics_Callback_Body_Type type, EPhysics_Body_Event_Cb func)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Callback *cb;
|
EPhysics_Body_Callback *cb;
|
||||||
void *cb_data;
|
void *cb_data = NULL;
|
||||||
|
|
||||||
if (!body)
|
if (!body)
|
||||||
{
|
{
|
||||||
|
@ -910,23 +939,23 @@ ephysics_body_event_callback_del(EPhysics_Body *body, EPhysics_Callback_Body_Typ
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
EINA_INLIST_FOREACH(body->callbacks, cb)
|
||||||
{
|
{
|
||||||
if ((cb->type == type) && (cb->func == func)) {
|
if ((cb->type != type) || (cb->func != func))
|
||||||
cb_data = cb->data;
|
continue;
|
||||||
body->callbacks = eina_inlist_remove(body->callbacks,
|
|
||||||
EINA_INLIST_GET(cb));
|
cb_data = cb->data;
|
||||||
free(cb);
|
_ephysics_body_event_callback_del(body, cb);
|
||||||
return cb_data;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return cb_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void *
|
EAPI void *
|
||||||
ephysics_body_event_callback_del_full(EPhysics_Body *body, EPhysics_Callback_Body_Type type, EPhysics_Body_Event_Cb func, void *data)
|
ephysics_body_event_callback_del_full(EPhysics_Body *body, EPhysics_Callback_Body_Type type, EPhysics_Body_Event_Cb func, void *data)
|
||||||
{
|
{
|
||||||
EPhysics_Body_Callback *cb;
|
EPhysics_Body_Callback *cb;
|
||||||
void *cb_data;
|
void *cb_data = NULL;
|
||||||
|
|
||||||
if (!body)
|
if (!body)
|
||||||
{
|
{
|
||||||
|
@ -936,16 +965,15 @@ ephysics_body_event_callback_del_full(EPhysics_Body *body, EPhysics_Callback_Bod
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(body->callbacks, cb)
|
EINA_INLIST_FOREACH(body->callbacks, cb)
|
||||||
{
|
{
|
||||||
if ((cb->type == type) && (cb->func == func) && (cb->data == data)) {
|
if ((cb->type != type) || (cb->func != func) || (cb->data != data))
|
||||||
cb_data = cb->data;
|
continue;
|
||||||
body->callbacks = eina_inlist_remove(body->callbacks,
|
|
||||||
EINA_INLIST_GET(cb));
|
cb_data = cb->data;
|
||||||
free(cb);
|
_ephysics_body_event_callback_del(body, cb);
|
||||||
return cb_data;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return cb_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
|
|
@ -59,10 +59,12 @@ struct _EPhysics_Body {
|
||||||
btRigidBody *rigid_body;
|
btRigidBody *rigid_body;
|
||||||
Evas_Object *evas_obj;
|
Evas_Object *evas_obj;
|
||||||
EPhysics_World *world;
|
EPhysics_World *world;
|
||||||
|
int walking;
|
||||||
void *data;
|
void *data;
|
||||||
Eina_Inlist *callbacks;
|
Eina_Inlist *callbacks;
|
||||||
double mass;
|
|
||||||
Eina_List *collision_groups;
|
Eina_List *collision_groups;
|
||||||
|
Eina_List *to_delete;
|
||||||
|
double mass;
|
||||||
Eina_Bool active:1;
|
Eina_Bool active:1;
|
||||||
Eina_Bool deleted:1;
|
Eina_Bool deleted:1;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue