showbase: Annotate basic `ShowBase` setup/shutdown methods (#1558)
This commit is contained in:
parent
583f7366db
commit
f5b0b1e1d6
|
|
@ -8,6 +8,9 @@ base = ShowBase.ShowBase()
|
|||
# Put an axis in the world:
|
||||
base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
|
||||
|
||||
assert base.camera is not None
|
||||
assert base.camLens is not None
|
||||
|
||||
base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
|
||||
base.camLens.setFov(52.0)
|
||||
base.camLens.setNearFar(1.0, 10000.0)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ base = ThreeUpShow.ThreeUpShow()
|
|||
# Put an axis in the world:
|
||||
base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
|
||||
|
||||
assert base.camera is not None
|
||||
assert base.camLens is not None
|
||||
|
||||
base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
|
||||
base.camLens.setFov(52.0)
|
||||
base.camLens.setNearFar(1.0, 10000.0)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ built-in scope.
|
|||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['ShowBase', 'WindowControls']
|
||||
|
||||
# This module redefines the builtin import function with one
|
||||
|
|
@ -71,9 +73,11 @@ from panda3d.core import (
|
|||
GraphicsPipe,
|
||||
GraphicsPipeSelection,
|
||||
GraphicsWindow,
|
||||
InputDevice,
|
||||
InputDeviceManager,
|
||||
InputDeviceNode,
|
||||
KeyboardButton,
|
||||
Lens,
|
||||
LensNode,
|
||||
Mat4,
|
||||
ModelNode,
|
||||
|
|
@ -118,9 +122,11 @@ from . import DConfig
|
|||
from direct.extensions_native import NodePath_extensions # pylint: disable=unused-import
|
||||
|
||||
# This needs to be available early for DirectGUI imports
|
||||
from typing import Any
|
||||
builtins: Any # Tell mypy not to worry about us setting attributes on builtins
|
||||
import sys
|
||||
import builtins
|
||||
builtins.config = DConfig # type: ignore[attr-defined]
|
||||
builtins.config = DConfig
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
|
||||
from direct.directnotify.Notifier import Notifier
|
||||
|
|
@ -141,7 +147,7 @@ import importlib
|
|||
from direct.showbase import ExceptionVarDump
|
||||
from . import DirectObject
|
||||
from . import SfxPlayer
|
||||
from typing import ClassVar, Optional
|
||||
from typing import Callable, ClassVar, Literal, NoReturn
|
||||
if __debug__:
|
||||
from direct.showbase import GarbageReport
|
||||
from direct.directutil import DeltaProfiler
|
||||
|
|
@ -150,9 +156,10 @@ if __debug__:
|
|||
|
||||
|
||||
@atexit.register
|
||||
def exitfunc():
|
||||
if getattr(builtins, 'base', None) is not None:
|
||||
builtins.base.destroy()
|
||||
def exitfunc() -> None:
|
||||
base = getattr(builtins, 'base', None)
|
||||
if base is not None:
|
||||
base.destroy()
|
||||
|
||||
# Now ShowBase is a DirectObject. We need this so ShowBase can hang
|
||||
# hooks on messages, particularly on window-event. This doesn't
|
||||
|
|
@ -170,7 +177,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
aspect2d: NodePath
|
||||
pixel2d: NodePath
|
||||
|
||||
def __init__(self, fStartDirect=True, windowType=None):
|
||||
def __init__(self, fStartDirect: bool = True, windowType: str | None = None) -> None:
|
||||
"""Opens a window, sets up a 3-D and several 2-D scene graphs, and
|
||||
everything else needed to render the scene graph to the window.
|
||||
|
||||
|
|
@ -233,10 +240,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.wantRender2dp = ConfigVariableBool('want-render2dp', True).value
|
||||
|
||||
self.screenshotExtension = ConfigVariableString('screenshot-extension', 'jpg').value
|
||||
self.musicManager = None
|
||||
self.musicManagerIsValid = None
|
||||
self.sfxManagerList = []
|
||||
self.sfxManagerIsValidList = []
|
||||
self.musicManager: AudioManager | None = None
|
||||
self.musicManagerIsValid: bool | None = None
|
||||
self.sfxManagerList: list[AudioManager] = []
|
||||
self.sfxManagerIsValidList: list[bool] = []
|
||||
|
||||
self.wantStats = ConfigVariableBool('want-pstats', False).value
|
||||
self.wantTk = False
|
||||
|
|
@ -245,12 +252,12 @@ class ShowBase(DirectObject.DirectObject):
|
|||
|
||||
#: Fill this in with a function to invoke when the user "exits"
|
||||
#: the program by closing the main window.
|
||||
self.exitFunc = None
|
||||
self.exitFunc: Callable[[], object] | None = None
|
||||
|
||||
#: Add final-exit callbacks to this list. These will be called
|
||||
#: when sys.exit() is called, after Panda has unloaded, and
|
||||
#: just before Python is about to shut down.
|
||||
self.finalExitCallbacks = []
|
||||
self.finalExitCallbacks: list[Callable[[], object]] = []
|
||||
|
||||
# Set up the TaskManager to reset the PStats clock back
|
||||
# whenever we resume from a pause. This callback function is
|
||||
|
|
@ -268,7 +275,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.__configAspectRatio = ConfigVariableDouble('aspect-ratio', 0).value
|
||||
# This variable is used to see if the aspect ratio has changed when
|
||||
# we get a window-event.
|
||||
self.__oldAspectRatio = None
|
||||
self.__oldAspectRatio: float | None = None
|
||||
|
||||
#: This is set to the value of the window-type config variable, but may
|
||||
#: optionally be overridden in the Showbase constructor. Should either
|
||||
|
|
@ -279,68 +286,68 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.requireWindow = ConfigVariableBool('require-window', True).value
|
||||
|
||||
#: This is the main, or only window; see `winList` for a list of *all* windows.
|
||||
self.win = None
|
||||
self.frameRateMeter = None
|
||||
self.sceneGraphAnalyzerMeter = None
|
||||
self.win: GraphicsOutput | None = None
|
||||
self.frameRateMeter: FrameRateMeter | None = None
|
||||
self.sceneGraphAnalyzerMeter: SceneGraphAnalyzerMeter | None = None
|
||||
#: A list of all windows opened via `openWindow()`.
|
||||
self.winList = []
|
||||
self.winControls = []
|
||||
self.mainWinMinimized = 0
|
||||
self.mainWinForeground = 0
|
||||
self.winList: list[GraphicsEngine] = []
|
||||
self.winControls: list[WindowControls] = []
|
||||
self.mainWinMinimized = False
|
||||
self.mainWinForeground = False
|
||||
#: Contains the :class:`~panda3d.core.GraphicsPipe` object created by
|
||||
#: `makeDefaultPipe()`.
|
||||
self.pipe = None
|
||||
self.pipe: GraphicsPipe | None = None
|
||||
#: The full list of :class:`~panda3d.core.GraphicsPipe` objects,
|
||||
#: including any auxiliary pipes. Filled by `makeAllPipes()`.
|
||||
self.pipeList = []
|
||||
self.mouse2cam = None
|
||||
self.buttonThrowers = None
|
||||
self.mouseWatcher = None
|
||||
self.pipeList: list[GraphicsPipe] = []
|
||||
self.mouse2cam: NodePath | None = None
|
||||
self.buttonThrowers: list[ButtonThrower] | None = None
|
||||
self.mouseWatcher: NodePath | None = None
|
||||
#: The :class:`~panda3d.core.MouseWatcher` object, created by
|
||||
#: `setupMouse()`.
|
||||
self.mouseWatcherNode = None
|
||||
self.pointerWatcherNodes = None
|
||||
self.mouseInterface = None
|
||||
self.drive = None
|
||||
self.trackball = None
|
||||
self.texmem = None
|
||||
self.showVertices = None
|
||||
self.deviceButtonThrowers = []
|
||||
self.mouseWatcherNode: MouseWatcher | None = None
|
||||
self.pointerWatcherNodes: list[MouseWatcher] | None = None
|
||||
self.mouseInterface: NodePath | None = None
|
||||
self.drive: NodePath | None = None
|
||||
self.trackball: NodePath | None = None
|
||||
self.texmem: Any | None = None
|
||||
self.showVertices: NodePath | None = None
|
||||
self.deviceButtonThrowers: list[NodePath] = []
|
||||
|
||||
#: This is a :class:`~panda3d.core.NodePath` pointing to the
|
||||
#: :class:`~panda3d.core.Camera` object set up for the 3D scene.
|
||||
#: Usually a child of `camera`.
|
||||
self.cam = None
|
||||
self.cam: NodePath | None = None
|
||||
#: Same as `cam`, but for the 2D scene graph.
|
||||
self.cam2d = None
|
||||
self.cam2d: NodePath | None = None
|
||||
#: Same as `cam2d`, but for the 2D overlay scene graph.
|
||||
self.cam2dp = None
|
||||
self.cam2dp: NodePath | None = None
|
||||
|
||||
#: This is the :class:`~panda3d.core.NodePath` that should be used to
|
||||
#: manipulate the camera. It points at the node to which the default
|
||||
#: camera (`cam`, `camNode`) is attached.
|
||||
self.camera = None
|
||||
self.camera: NodePath | None = None
|
||||
#: Same as `camera`, but for the 2D scene graph. Parent of `cam2d`.
|
||||
self.camera2d = None
|
||||
self.camera2d: NodePath | None = None
|
||||
#: Same as `camera2d`, but for the 2D overlay scene graph. Parent of
|
||||
#: `cam2dp`.
|
||||
self.camera2dp = None
|
||||
self.camera2dp: NodePath | None = None
|
||||
|
||||
#: A list of all cameras created with `makeCamera()`, including `cam`.
|
||||
self.camList = []
|
||||
self.camList: list[NodePath] = []
|
||||
#: Convenience accessor for base.cam.node(), containing a
|
||||
#: :class:`~panda3d.core.Camera` object.
|
||||
self.camNode = None
|
||||
self.camNode: Camera | None = None
|
||||
#: Convenience accessor for base.camNode.get_lens(), containing a
|
||||
#: :class:`~panda3d.core.Lens` object.
|
||||
self.camLens = None
|
||||
self.camFrustumVis = None
|
||||
self.camLens: Lens | None = None
|
||||
self.camFrustumVis: NodePath | None = None
|
||||
self.direct = None
|
||||
#: This is used to store the wx.Application object used when want-wx is
|
||||
#: set or `startWx()` is called.
|
||||
self.wxApp = None
|
||||
self.wxApp: Any | None = None
|
||||
self.wxAppCreated = False
|
||||
self.tkRoot = None
|
||||
self.tkRoot: Any | None = None
|
||||
self.tkRootCreated = False
|
||||
|
||||
# This is used for syncing multiple PCs in a distributed cluster
|
||||
|
|
@ -371,11 +378,11 @@ class ShowBase(DirectObject.DirectObject):
|
|||
#: traverse it automatically in the collisionLoop task, so you won't
|
||||
#: need to call :meth:`~panda3d.core.CollisionTraverser.traverse()`
|
||||
#: yourself every frame.
|
||||
self.cTrav = 0
|
||||
self.shadowTrav = 0
|
||||
self.cTrav: CollisionTraverser | Literal[0] = 0
|
||||
self.shadowTrav: CollisionTraverser | Literal[0] = 0
|
||||
self.cTravStack = Stack()
|
||||
# Ditto for an AppTraverser.
|
||||
self.appTrav = 0
|
||||
self.appTrav: Any | Literal[0] = 0
|
||||
|
||||
# This is the DataGraph traverser, which we might as well
|
||||
# create now.
|
||||
|
|
@ -383,7 +390,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
|
||||
# Maybe create a RecorderController to record and/or play back
|
||||
# the user session.
|
||||
self.recorder = None
|
||||
self.recorder: RecorderController | None = None
|
||||
playbackSession = ConfigVariableFilename('playback-session', '')
|
||||
recordSession = ConfigVariableFilename('record-session', '')
|
||||
if not playbackSession.empty():
|
||||
|
|
@ -448,22 +455,22 @@ class ShowBase(DirectObject.DirectObject):
|
|||
#: If `enableParticles()` has been called, this is the particle manager
|
||||
#: as imported from :mod:`direct.particles.ParticleManagerGlobal`.
|
||||
self.particleMgr = None
|
||||
self.particleMgrEnabled = 0
|
||||
self.particleMgrEnabled = False
|
||||
|
||||
#: If `enableParticles()` has been called, this is the physics manager
|
||||
#: as imported from :mod:`direct.showbase.PhysicsManagerGlobal`.
|
||||
self.physicsMgr = None
|
||||
self.physicsMgrEnabled = 0
|
||||
self.physicsMgrAngular = 0
|
||||
self.physicsMgrEnabled = False
|
||||
self.physicsMgrAngular = False
|
||||
|
||||
#: This is the global :class:`~panda3d.core.InputDeviceManager`, which
|
||||
#: keeps track of connected input devices.
|
||||
self.devices = InputDeviceManager.getGlobalPtr()
|
||||
self.__inputDeviceNodes = {}
|
||||
self.__inputDeviceNodes: dict[InputDevice, NodePath] = {}
|
||||
|
||||
self.createStats()
|
||||
|
||||
self.AppHasAudioFocus = 1
|
||||
self.AppHasAudioFocus = True
|
||||
|
||||
# Get a pointer to Panda's global ClockObject, used for
|
||||
# synchronizing events between Python and C.
|
||||
|
|
@ -502,7 +509,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
affinity = ConfigVariableInt('client-cpu-affinity', -1).value
|
||||
if (affinity in (None, -1)) and autoAffinity:
|
||||
affinity = 0
|
||||
if affinity not in (None, -1):
|
||||
if affinity is not None and affinity != -1:
|
||||
# Windows XP supports a 32-bit affinity mask
|
||||
TrueClock.getGlobalPtr().setCpuAffinity(1 << (affinity % 32))
|
||||
|
||||
|
|
@ -575,7 +582,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
# Now hang a hook on the window-event from Panda. This allows
|
||||
# us to detect when the user resizes, minimizes, or closes the
|
||||
# main window.
|
||||
self.__prevWindowProperties = None
|
||||
self.__prevWindowProperties: WindowProperties | None = None
|
||||
self.__directObject.accept('window-event', self.windowEvent)
|
||||
|
||||
# Transition effects (fade, iris, etc)
|
||||
|
|
@ -658,7 +665,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
#print getDnaPath()
|
||||
print("}")
|
||||
|
||||
def destroy(self):
|
||||
def destroy(self) -> None:
|
||||
""" Call this function to destroy the ShowBase and stop all
|
||||
its tasks, freeing all of the Panda resources. Normally, you
|
||||
should not need to call it explicitly, as it is bound to the
|
||||
|
|
@ -704,6 +711,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.shutdown()
|
||||
|
||||
if getattr(self, 'musicManager', None):
|
||||
assert self.musicManager is not None
|
||||
self.musicManager.shutdown()
|
||||
self.musicManager = None
|
||||
for sfxManager in self.sfxManagerList:
|
||||
|
|
@ -711,12 +719,12 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.sfxManagerList = []
|
||||
if getattr(self, 'loader', None):
|
||||
self.loader.destroy()
|
||||
self.loader = None
|
||||
del self.loader
|
||||
if getattr(self, 'graphicsEngine', None):
|
||||
self.graphicsEngine.removeAllWindows()
|
||||
|
||||
try:
|
||||
self.direct.panel.destroy()
|
||||
self.direct.panel.destroy() # type: ignore[attr-defined]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
@ -1185,7 +1193,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.setSceneGraphAnalyzerMeter(flag.value)
|
||||
return success
|
||||
|
||||
def setSleep(self, amount):
|
||||
def setSleep(self, amount: float) -> None:
|
||||
"""
|
||||
Sets up a task that calls python 'sleep' every frame. This is a simple
|
||||
way to reduce the CPU usage (and frame rate) of a panda program.
|
||||
|
|
@ -1205,7 +1213,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
#time.sleep(self.clientSleep)
|
||||
return Task.cont
|
||||
|
||||
def setFrameRateMeter(self, flag):
|
||||
def setFrameRateMeter(self, flag: bool) -> None:
|
||||
"""
|
||||
Turns on or off (according to flag) a standard frame rate
|
||||
meter in the upper-right corner of the main window.
|
||||
|
|
@ -1219,7 +1227,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.frameRateMeter.clearWindow()
|
||||
self.frameRateMeter = None
|
||||
|
||||
def setSceneGraphAnalyzerMeter(self, flag):
|
||||
def setSceneGraphAnalyzerMeter(self, flag: bool) -> None:
|
||||
"""
|
||||
Turns on or off (according to flag) a standard frame rate
|
||||
meter in the upper-right corner of the main window.
|
||||
|
|
@ -1242,7 +1250,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
mouseKeyboard = self.dataRoot.find("**/*"))
|
||||
self.winControls.append(winCtrl)
|
||||
|
||||
def setupRender(self):
|
||||
def setupRender(self) -> None:
|
||||
"""
|
||||
Creates the render scene graph, the primary scene graph for
|
||||
rendering 3-d geometry.
|
||||
|
|
@ -1252,11 +1260,11 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.render.setAttrib(RescaleNormalAttrib.makeDefault())
|
||||
|
||||
self.render.setTwoSided(0)
|
||||
self.backfaceCullingEnabled = 1
|
||||
self.textureEnabled = 1
|
||||
self.wireframeEnabled = 0
|
||||
self.backfaceCullingEnabled = True
|
||||
self.textureEnabled = True
|
||||
self.wireframeEnabled = False
|
||||
|
||||
def setupRender2d(self):
|
||||
def setupRender2d(self) -> None:
|
||||
"""
|
||||
Creates the render2d scene graph, the primary scene graph for
|
||||
2-d objects and gui elements that are superimposed over the
|
||||
|
|
@ -1355,7 +1363,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
if xsize > 0 and ysize > 0:
|
||||
self.pixel2d.setScale(2.0 / xsize, 1.0, 2.0 / ysize)
|
||||
|
||||
def setupRender2dp(self):
|
||||
def setupRender2dp(self) -> None:
|
||||
"""
|
||||
Creates a render2d scene graph, the secondary scene graph for
|
||||
2-d objects and gui elements that are superimposed over the
|
||||
|
|
@ -1677,7 +1685,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
|
||||
return camera2dp
|
||||
|
||||
def setupDataGraph(self):
|
||||
def setupDataGraph(self) -> None:
|
||||
"""
|
||||
Creates the data graph and populates it with the basic input
|
||||
devices.
|
||||
|
|
@ -2006,7 +2014,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.physicsMgr.doPhysics(dt)
|
||||
return Task.cont
|
||||
|
||||
def createStats(self, hostname=None, port=None):
|
||||
def createStats(self, hostname: str | None = None, port: int | None = None) -> bool:
|
||||
"""
|
||||
If want-pstats is set in Config.prc, or the `wantStats` member is
|
||||
otherwise set to True, connects to the PStats server.
|
||||
|
|
@ -2323,7 +2331,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
throw_new_frame()
|
||||
return Task.cont
|
||||
|
||||
def restart(self, clusterSync=False, cluster=None):
|
||||
def restart(self, clusterSync: bool = False, cluster=None) -> None:
|
||||
self.shutdown()
|
||||
# __resetPrevTransform goes at the very beginning of the frame.
|
||||
self.taskMgr.add(
|
||||
|
|
@ -2354,7 +2362,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||
self.taskMgr.add(self.__audioLoop, 'audioLoop', sort = 60)
|
||||
self.eventMgr.restart()
|
||||
|
||||
def shutdown(self):
|
||||
def shutdown(self) -> None:
|
||||
self.taskMgr.remove('audioLoop')
|
||||
self.taskMgr.remove('igLoop')
|
||||
self.taskMgr.remove('shadowCollisionLoop')
|
||||
|
|
@ -3195,14 +3203,14 @@ class ShowBase(DirectObject.DirectObject):
|
|||
# If anybody needs to update their GUI, put a callback on this event
|
||||
messenger.send("aspectRatioChanged")
|
||||
|
||||
def userExit(self):
|
||||
def userExit(self) -> NoReturn:
|
||||
# The user has requested we exit the program. Deal with this.
|
||||
if self.exitFunc:
|
||||
self.exitFunc()
|
||||
self.notify.info("Exiting ShowBase.")
|
||||
self.finalizeExit()
|
||||
|
||||
def finalizeExit(self):
|
||||
def finalizeExit(self) -> NoReturn:
|
||||
"""
|
||||
Called by `userExit()` to quit the application. The default
|
||||
implementation just calls `sys.exit()`.
|
||||
|
|
|
|||
Loading…
Reference in New Issue