Dentosal / python-sc2

A StarCraft II bot api client library for Python 3
MIT License
586 stars 182 forks source link

split already_pending #209

Closed drakonnan1st closed 5 years ago

drakonnan1st commented 5 years ago

Current version of already_pending:

    def already_pending(self, unit_type: Union[UpgradeId, UnitTypeId], all_units: bool=False) -> int:
        # TODO / FIXME: SCV building a structure might be counted as two units

        if isinstance(unit_type, UpgradeId):
            return self.already_pending_upgrade(unit_type)

        ability = self._game_data.units[unit_type.value].creation_ability

        amount = len(self.units(unit_type).not_ready)

        if all_units:
            amount += sum([o.ability == ability for u in self.units for o in u.orders])
        else:
            amount += sum([o.ability == ability for w in self.workers for o in w.orders])
            amount += sum([egg.orders[0].ability == ability for egg in self.units(UnitTypeId.EGG)])

        return amount

Regardless of what we're trying to find, the function will always loop over self.units, self.workers, and self.units(UnitTypeId.EGG), even when not needed. This slows down the function, which is more noticeable when it is called many times. Maybe it would be better to split it based on the requested unit type (e.g. already_pending_eggs, already_pending_units, already_pending_buildings)

BurnySc2 commented 5 years ago

Already submitted a version that will reduce the loop to once per frame:

https://github.com/Dentosal/python-sc2/pull/202/files#diff-6db6c51856eb1f881634e4fa09e9fe79R395

tweakimp commented 5 years ago

I think this is solved then, feel free to reopen if there is something else.