Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bindings|Fixed: Finding matching bindings with conditions
Until now a binding's conditions were not taken into consideration
when finding matching bindings. Fixes a problem where creating
a new binding would overwrite an existing one with different
conditions.
  • Loading branch information
skyjake committed Apr 5, 2012
1 parent 8707fc1 commit c6861b2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 19 deletions.
1 change: 1 addition & 0 deletions doomsday/engine/portable/include/b_util.h
Expand Up @@ -74,6 +74,7 @@ boolean B_ParseAnglePosition(const char* desc, float* pos);
boolean B_ParseStateCondition(statecondition_t* cond, const char* desc);
boolean B_CheckAxisPos(ebstate_t test, float testPos, float pos);
boolean B_CheckCondition(statecondition_t* cond, int localNum, struct bcontext_s* context);
boolean B_EqualConditions(const statecondition_t* a, const statecondition_t* b);
void B_AppendDeviceDescToString(uint device, ddeventtype_t type, int id, ddstring_t* str);
void B_AppendToggleStateToString(ebstate_t state, ddstring_t* str);
void B_AppendAxisPositionToString(ebstate_t state, float pos, ddstring_t* str);
Expand Down
58 changes: 40 additions & 18 deletions doomsday/engine/portable/src/b_context.c
Expand Up @@ -712,6 +712,34 @@ int B_BindingsForControl(int localPlayer, const char* controlName,
return numFound;
}

boolean B_AreConditionsEqual(int count1, const statecondition_t* conds1,
int count2, const statecondition_t* conds2)
{
int i, k;

// Quick test (assumes there are no duplicated conditions).
if(count1 != count2) return false;

for(i = 0; i < count1; ++i)
{
boolean found = false;
for(k = 0; k < count2; ++k)
{
if(B_EqualConditions(conds1 + i, conds2 + k))
{
found = true;
break;
}
}
if(!found) return false;
}
return true;
}

/**
* Looks through context @a bc and looks for a binding that matches either
* @a match1 or @a match2.
*/
boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1,
dbinding_t* match2, evbinding_t** evResult,
dbinding_t** dResult)
Expand All @@ -726,24 +754,21 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1,

for(e = bc->commandBinds.next; e != &bc->commandBinds; e = e->next)
{
// TODO: A bit lazy here, should also match all the conditions.
// Now we just consider all bindings with conditions unique...
if(e->numConds)
continue;

if(match1 && match1->bid != e->bid)
{
if(match1->device == e->device && match1->id == e->id &&
match1->type == e->type && match1->state == e->state)
if(B_AreConditionsEqual(match1->numConds, match1->conds, e->numConds, e->conds) &&
match1->device == e->device && match1->id == e->id &&
match1->type == e->type && match1->state == e->state)
{
*evResult = e;
return true;
}
}
if(match2)
{
if(match2->device == e->device && match2->id == e->id &&
match2->type == e->type)
if(B_AreConditionsEqual(match2->numConds, match2->conds, e->numConds, e->conds) &&
match2->device == e->device && match2->id == e->id &&
match2->type == e->type)
{
*evResult = e;
return true;
Expand All @@ -757,15 +782,11 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1,
{
for(d = c->deviceBinds[i].next; d != &c->deviceBinds[i]; d = d->next)
{
// Should also match all the conditions, now we just
// consider all bindings with conditions unique...
if(d->numConds)
continue;

if(match1)
{
if(match1->device == d->device && match1->id == d->id &&
match1->type == d->type)
if(B_AreConditionsEqual(match1->numConds, match1->conds, d->numConds, d->conds) &&
match1->device == d->device && match1->id == d->id &&
match1->type == d->type)
{
*dResult = d;
return true;
Expand All @@ -774,8 +795,9 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1,

if(match2 && match2->bid != d->bid)
{
if(match2->device == d->device && match2->id == d->id &&
match2->type == d->type)
if(B_AreConditionsEqual(match2->numConds, match2->conds, d->numConds, d->conds) &&
match2->device == d->device && match2->id == d->id &&
match2->type == d->type)
{
*dResult = d;
return true;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/src/b_main.c
Expand Up @@ -314,7 +314,7 @@ void B_DeleteMatching(bcontext_t* bc, evbinding_t* eventBinding,
while(B_FindMatchingBinding(bc, eventBinding, deviceBinding, &evb, &devb))
{
// Only either evb or devb is returned as non-NULL.
int bid = (evb? evb->bid : (devb? devb->bid : 0));
int bid = (evb? evb->bid : (devb? devb->bid : 0));

if(bid)
{
Expand Down
11 changes: 11 additions & 0 deletions doomsday/engine/portable/src/b_util.c
Expand Up @@ -495,6 +495,17 @@ boolean B_CheckCondition(statecondition_t* cond, int localNum, bcontext_t* conte
return !fulfilled;
}

boolean B_EqualConditions(const statecondition_t* a, const statecondition_t* b)
{
return (a->device == b->device &&
a->type == b->type &&
a->id == b->id &&
a->state == b->state &&
FEQUAL(a->pos, b->pos) &&
a->flags.negate == b->flags.negate &&
a->flags.multiplayer == b->flags.multiplayer);
}

void B_AppendDeviceDescToString(uint device, ddeventtype_t type, int id, ddstring_t* str)
{
inputdev_t* dev = I_GetDevice(device, false);
Expand Down

0 comments on commit c6861b2

Please sign in to comment.