diff --git a/assets/src/ba_data/python/ba/_actor.py b/assets/src/ba_data/python/ba/_actor.py index c86a7be1..2121940e 100644 --- a/assets/src/ba_data/python/ba/_actor.py +++ b/assets/src/ba_data/python/ba/_actor.py @@ -26,7 +26,7 @@ import weakref from typing import TYPE_CHECKING, TypeVar, overload from ba._messages import DieMessage, DeathType, OutOfBoundsMessage, UNHANDLED -from ba._error import print_error, print_exception, ActivityNotFoundError +from ba._error import print_exception, ActivityNotFoundError import _ba if TYPE_CHECKING: @@ -106,8 +106,7 @@ class Actor: def handlemessage(self, msg: Any) -> Any: """General message handling; can be passed any message object.""" - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired # By default, actors going out-of-bounds simply kill themselves. if isinstance(msg, OutOfBoundsMessage): @@ -135,9 +134,9 @@ class Actor: def on_expire(self) -> None: """Called for remaining ba.Actors when their ba.Activity shuts down. - Actors can use this opportunity to clear callbacks - or other references which have the potential of keeping the - ba.Activity alive inadvertently (Activities can not exit cleanly while + Actors can use this opportunity to clear callbacks or other + references which have the potential of keeping the ba.Activity + alive inadvertently (Activities can not exit cleanly while any Python references to them remain.) Once an actor is expired (see ba.Actor.is_expired()) it should no @@ -189,22 +188,6 @@ class Actor: """ return True - def _handlemessage_sanity_check(self) -> None: - """Make sure things are kosher in handlemessage(). - - Place this in an 'if __debug__:' clause at the top of handlemessage() - overrides. This will will complain if anything is sending the Actor - messages after the activity has ended, which should be explicitly - avoided. - """ - if not __debug__: - print_error('This should only be called in __debug__ mode.', - once=True) - if not getattr(self, '_root_actor_init_called', False): - print_error('Root Actor __init__() not called.') - if self.expired: - print_error(f'handlemessage() called on expired actor: {self}') - @property def activity(self) -> ba.Activity: """The Activity this Actor was created in. diff --git a/assets/src/ba_data/python/bastd/actor/background.py b/assets/src/ba_data/python/bastd/actor/background.py index 86b0031a..60f05f44 100644 --- a/assets/src/ba_data/python/bastd/actor/background.py +++ b/assets/src/ba_data/python/bastd/actor/background.py @@ -150,8 +150,7 @@ class Background(ba.Actor): ba.timer(self.fade_time + 0.1, self.node.delete) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): self._die(msg.immediate) else: diff --git a/assets/src/ba_data/python/bastd/actor/bomb.py b/assets/src/ba_data/python/bastd/actor/bomb.py index 757af48d..e33852a5 100644 --- a/assets/src/ba_data/python/bastd/actor/bomb.py +++ b/assets/src/ba_data/python/bastd/actor/bomb.py @@ -626,8 +626,7 @@ class Blast(ba.Actor): ba.timer(0.4, _extra_debris_sound) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: diff --git a/assets/src/ba_data/python/bastd/actor/controlsguide.py b/assets/src/ba_data/python/bastd/actor/controlsguide.py index a149ba75..bfb33de6 100644 --- a/assets/src/ba_data/python/bastd/actor/controlsguide.py +++ b/assets/src/ba_data/python/bastd/actor/controlsguide.py @@ -468,8 +468,7 @@ class ControlsGuide(ba.Actor): return not self._dead def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if msg.immediate: self._die() diff --git a/assets/src/ba_data/python/bastd/actor/flag.py b/assets/src/ba_data/python/bastd/actor/flag.py index 0e5b014f..b8cad76e 100644 --- a/assets/src/ba_data/python/bastd/actor/flag.py +++ b/assets/src/ba_data/python/bastd/actor/flag.py @@ -343,8 +343,7 @@ class Flag(ba.Actor): 1.0, ba.WeakCall(self._hide_score_text)) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() diff --git a/assets/src/ba_data/python/bastd/actor/image.py b/assets/src/ba_data/python/bastd/actor/image.py index 05aff991..9ef97066 100644 --- a/assets/src/ba_data/python/bastd/actor/image.py +++ b/assets/src/ba_data/python/bastd/actor/image.py @@ -181,8 +181,7 @@ class Image(ba.Actor): ba.WeakCall(self.handlemessage, ba.DieMessage())) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() diff --git a/assets/src/ba_data/python/bastd/actor/playerspaz.py b/assets/src/ba_data/python/bastd/actor/playerspaz.py index 1a3375a1..1c706cd0 100644 --- a/assets/src/ba_data/python/bastd/actor/playerspaz.py +++ b/assets/src/ba_data/python/bastd/actor/playerspaz.py @@ -90,6 +90,8 @@ class PlayerSpaz(Spaz): self._player = player self._drive_player_position() + # Overloads to tell the type system our return type based on doraise val. + @overload def getplayer(self, playertype: Type[PlayerType], @@ -144,9 +146,9 @@ class PlayerSpaz(Spaz): player.assign_input_call('upDown', self.on_move_up_down) player.assign_input_call('leftRight', self.on_move_left_right) player.assign_input_call('holdPositionPress', - self._on_hold_position_press) + self.on_hold_position_press) player.assign_input_call('holdPositionRelease', - self._on_hold_position_release) + self.on_hold_position_release) if enable_jump: player.assign_input_call('jumpPress', self.on_jump_press) player.assign_input_call('jumpRelease', self.on_jump_release) @@ -179,7 +181,7 @@ class PlayerSpaz(Spaz): # Send releases for anything in case its held. self.on_move_up_down(0) self.on_move_left_right(0) - self._on_hold_position_release() + self.on_hold_position_release() self.on_jump_release() self.on_pickup_release() self.on_punch_release() @@ -195,8 +197,7 @@ class PlayerSpaz(Spaz): # pylint: disable=too-many-branches # pylint: disable=too-many-statements # pylint: disable=too-many-nested-blocks - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired # Keep track of if we're being held and by who most recently. if isinstance(msg, ba.PickedUpMessage): @@ -292,7 +293,8 @@ class PlayerSpaz(Spaz): if activity is not None and self._player.exists(): activity.handlemessage(PlayerSpazHurtMessage(self)) else: - super().handlemessage(msg) + return super().handlemessage(msg) + return None def _drive_player_position(self) -> None: """Drive our ba.Player's official position diff --git a/assets/src/ba_data/python/bastd/actor/popuptext.py b/assets/src/ba_data/python/bastd/actor/popuptext.py index 134811fe..c3e23809 100644 --- a/assets/src/ba_data/python/bastd/actor/popuptext.py +++ b/assets/src/ba_data/python/bastd/actor/popuptext.py @@ -122,8 +122,7 @@ class PopupText(ba.Actor): lifespan, ba.WeakCall(self.handlemessage, ba.DieMessage())) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() diff --git a/assets/src/ba_data/python/bastd/actor/powerupbox.py b/assets/src/ba_data/python/bastd/actor/powerupbox.py index 2af9a7fd..0a4053e1 100644 --- a/assets/src/ba_data/python/bastd/actor/powerupbox.py +++ b/assets/src/ba_data/python/bastd/actor/powerupbox.py @@ -293,9 +293,7 @@ class PowerupBox(ba.Actor): self.node.flashing = True def handlemessage(self, msg: Any) -> Any: - # pylint: disable=too-many-branches - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.PowerupAcceptMessage): factory = PowerupBoxFactory.get() @@ -330,4 +328,5 @@ class PowerupBox(ba.Actor): if msg.hit_type != 'punch': self.handlemessage(ba.DieMessage()) else: - super().handlemessage(msg) + return super().handlemessage(msg) + return None diff --git a/assets/src/ba_data/python/bastd/actor/spaz.py b/assets/src/ba_data/python/bastd/actor/spaz.py index 5d769078..8e13d6a4 100644 --- a/assets/src/ba_data/python/bastd/actor/spaz.py +++ b/assets/src/ba_data/python/bastd/actor/spaz.py @@ -428,7 +428,7 @@ class Spaz(ba.Actor): return self.node.pickup_pressed = False - def _on_hold_position_press(self) -> None: + def on_hold_position_press(self) -> None: """ Called to 'press hold-position' on this spaz; used for player or AI connections. @@ -438,7 +438,7 @@ class Spaz(ba.Actor): self.node.hold_position_pressed = True self._turbo_filter_add_press('holdposition') - def _on_hold_position_release(self) -> None: + def on_hold_position_release(self) -> None: """ Called to 'release hold-position' on this spaz; used for player or AI connections. @@ -695,8 +695,7 @@ class Spaz(ba.Actor): # pylint: disable=too-many-return-statements # pylint: disable=too-many-statements # pylint: disable=too-many-branches - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.PickedUpMessage): if self.node: diff --git a/assets/src/ba_data/python/bastd/actor/spazbot.py b/assets/src/ba_data/python/bastd/actor/spazbot.py index 303beb37..bd7ebc23 100644 --- a/assets/src/ba_data/python/bastd/actor/spazbot.py +++ b/assets/src/ba_data/python/bastd/actor/spazbot.py @@ -510,8 +510,7 @@ class SpazBot(Spaz): def handlemessage(self, msg: Any) -> Any: # pylint: disable=too-many-branches - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired # Keep track of if we're being held and by who most recently. if isinstance(msg, ba.PickedUpMessage): diff --git a/assets/src/ba_data/python/bastd/actor/text.py b/assets/src/ba_data/python/bastd/actor/text.py index 0afccf5b..5864768f 100644 --- a/assets/src/ba_data/python/bastd/actor/text.py +++ b/assets/src/ba_data/python/bastd/actor/text.py @@ -229,8 +229,7 @@ class Text(ba.Actor): ba.WeakCall(self.handlemessage, ba.DieMessage())) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() diff --git a/assets/src/ba_data/python/bastd/actor/tipstext.py b/assets/src/ba_data/python/bastd/actor/tipstext.py index 3bd77347..33df2801 100644 --- a/assets/src/ba_data/python/bastd/actor/tipstext.py +++ b/assets/src/ba_data/python/bastd/actor/tipstext.py @@ -103,8 +103,7 @@ class TipsText(ba.Actor): self.node.text = next_tip def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if self.node: self.node.delete() diff --git a/assets/src/ba_data/python/bastd/actor/zoomtext.py b/assets/src/ba_data/python/bastd/actor/zoomtext.py index cade5ca0..192c6d18 100644 --- a/assets/src/ba_data/python/bastd/actor/zoomtext.py +++ b/assets/src/ba_data/python/bastd/actor/zoomtext.py @@ -171,8 +171,7 @@ class ZoomText(ba.Actor): ba.DieMessage())) def handlemessage(self, msg: Any) -> Any: - if __debug__: - self._handlemessage_sanity_check() + assert not self.expired if isinstance(msg, ba.DieMessage): if not self._dying and self.node: self._dying = True diff --git a/docs/ba_module.md b/docs/ba_module.md index 75bccd57..456f465d 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,5 +1,5 @@ -
This page documents the Python classes and functions in the 'ba' module, which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!
Called for remaining ba.Actors when their ba.Activity shuts down.
-Actors can use this opportunity to clear callbacks -or other references which have the potential of keeping the -ba.Activity alive inadvertently (Activities can not exit cleanly while +
Actors can use this opportunity to clear callbacks or other +references which have the potential of keeping the ba.Activity +alive inadvertently (Activities can not exit cleanly while any Python references to them remain.)
Once an actor is expired (see ba.Actor.is_expired()) it should no diff --git a/tools/efrotools/filecache.py b/tools/efrotools/filecache.py index 4dcf9634..1d582e38 100644 --- a/tools/efrotools/filecache.py +++ b/tools/efrotools/filecache.py @@ -105,7 +105,7 @@ class FileCache: # if anything has been modified, don't write. for fname, mtime in self.mtimes.items(): if os.path.getmtime(fname) != mtime: - print(f'{Clr.YLW}File changed during run:' + print(f'{Clr.MAG}File changed during run:' f' "{fname}"; cache not updated.{Clr.RST}') return out = json.dumps(self.entries)