- changed AInventory::HandlePickup to work iteratively instead of recursively.
Two reasons for this: 1. if this has to be routed through the VM each recursion will cost 1000 bytes of stack space which simply is not good. 2. having the virtual function only care about the item itself but not the entire inventory chain is a lot less error prone for scripting. Since the scripting interface needs a separate caller function anyway this seemed like a good time to change it. The same will be done for the other chained inventory handlers as well.
This commit is contained in:
parent
6eff1cb8be
commit
096c51d546
18 changed files with 55 additions and 72 deletions
|
|
@ -183,10 +183,6 @@ bool AAmmo::HandlePickup (AInventory *item)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
return Inventory->HandlePickup (item);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -718,13 +714,39 @@ bool AInventory::HandlePickup (AInventory *item)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AInventory, HandlePickup)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AInventory);
|
||||
PARAM_OBJECT(item, AInventory);
|
||||
ACTION_RETURN_BOOL(self->HandlePickup(item));
|
||||
}
|
||||
|
||||
bool AInventory::CallHandlePickup(AInventory *item)
|
||||
{
|
||||
auto self = this;
|
||||
while (self != nullptr)
|
||||
{
|
||||
return Inventory->HandlePickup (item);
|
||||
IFVIRTUAL(AActor, HandlePickup)
|
||||
{
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[2] = { (DObject*)self, (DObject*)item };
|
||||
VMReturn ret;
|
||||
VMFrameStack stack;
|
||||
int retval;
|
||||
ret.IntAt(&retval);
|
||||
stack.Call(func, params, 2, &ret, 1, nullptr);
|
||||
if (retval) return true;
|
||||
}
|
||||
else if (self->HandlePickup(item)) return true;
|
||||
self = self->Inventory;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: GoAway
|
||||
|
|
@ -1480,7 +1502,7 @@ bool AInventory::TryPickup (AActor *&toucher)
|
|||
// picked up, then it leaves the flag cleared.
|
||||
|
||||
ItemFlags &= ~IF_PICKUPGOOD;
|
||||
if (toucher->Inventory != NULL && toucher->Inventory->HandlePickup (this))
|
||||
if (toucher->Inventory != NULL && toucher->Inventory->CallHandlePickup (this))
|
||||
{
|
||||
// Let something else the player is holding intercept the pickup.
|
||||
if (!(ItemFlags & IF_PICKUPGOOD))
|
||||
|
|
@ -1892,10 +1914,6 @@ bool AHealthPickup::HandlePickup (AInventory *item)
|
|||
{
|
||||
return Super::HandlePickup (item);
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
return Inventory->HandlePickup (item);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2044,14 +2062,7 @@ bool ABackpackItem::HandlePickup (AInventory *item)
|
|||
item->ItemFlags |= IF_PICKUPGOOD;
|
||||
return true;
|
||||
}
|
||||
else if (Inventory != NULL)
|
||||
{
|
||||
return Inventory->HandlePickup (item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue