From 6d861f4088b20e6ade4c28ef37252a78c74bdb97 Mon Sep 17 00:00:00 2001
From: Eric Froemling
Date: Fri, 29 May 2020 15:51:36 -0700
Subject: [PATCH] Simplified handlemessage sanity checks
---
assets/src/ba_data/python/ba/_actor.py | 27 ++++---------------
.../ba_data/python/bastd/actor/background.py | 3 +--
assets/src/ba_data/python/bastd/actor/bomb.py | 3 +--
.../python/bastd/actor/controlsguide.py | 3 +--
assets/src/ba_data/python/bastd/actor/flag.py | 3 +--
.../src/ba_data/python/bastd/actor/image.py | 3 +--
.../ba_data/python/bastd/actor/playerspaz.py | 14 +++++-----
.../ba_data/python/bastd/actor/popuptext.py | 3 +--
.../ba_data/python/bastd/actor/powerupbox.py | 7 +++--
assets/src/ba_data/python/bastd/actor/spaz.py | 7 +++--
.../src/ba_data/python/bastd/actor/spazbot.py | 3 +--
assets/src/ba_data/python/bastd/actor/text.py | 3 +--
.../ba_data/python/bastd/actor/tipstext.py | 3 +--
.../ba_data/python/bastd/actor/zoomtext.py | 3 +--
docs/ba_module.md | 8 +++---
tools/efrotools/filecache.py | 2 +-
16 files changed, 34 insertions(+), 61 deletions(-)
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 @@
-last updated on 2020-05-29 for Ballistica version 1.5.0 build 20033
+last updated on 2020-05-29 for Ballistica version 1.5.0 build 20034
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!
@@ -741,9 +741,9 @@ they are Alive or not.
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)