Pstat decorator & base

Trying to use the example code for custom pstat collector panda3d.org/manual/index.php … ith_PStats

Getting this error:

Traceback (most recent call last):
  File "C:\Users\USER\workspace\main.py", line 10, in <module>
    from Game import Game
  File "C:\Users\USER\workspace\Game.py", line 7, in <module>
    from controllers.PlayerController import PlayerController
  File "C:\Users\USER\workspace\controllers\PlayerController.py", line 13, in <module>
    class PlayerController(DirectObject):
  File "C:\Users\USER\workspace\controllers\PlayerController.py", line 19, in PlayerController
    @pstat
  File "C:\Users\USER\workspace\PStats.py", line 7, in pstat
    if hasattr(base, 'custom_collectors'):
NameError: global name 'base' is not defined

PlayerController.py

from Pstats import pstat
...

    @pstat
    def Update(self, deltaTime, keysPressed, camera):
        ....

Pstats.py

def pstat(func):
    from pandac.PandaModules import PStatCollector
    collectorName = "Debug:%s" % func.__name__
    if hasattr(base, 'custom_collectors'):
        if collectorName in base.custom_collectors.keys():
            pstat = base.custom_collectors[collectorName]
        else:
            base.custom_collectors[collectorName] = PStatCollector(collectorName)
            pstat = base.custom_collectors[collectorName]
    else:
        base.custom_collectors = {}
        base.custom_collectors[collectorName] = PStatCollector(collectorName)
        pstat = base.custom_collectors[collectorName]
    def doPstat(*args, **kargs):
        pstat.start()
        returned = func(*args, **kargs)
        pstat.stop()
        return returned
    doPstat.__name__ = func.__name__
    doPstat.__dict__ = func.__dict__
    doPstat.__doc__ = func.__doc__
    return doPstat

The global “base” doesn’t exist until you have created a ShowBase instance, so make sure you do that before calling any of these decorated methods.

David

I’m using the decorator after I’ve created showbase window, but it looks like it’s crashing on import. If I import Direct start at the top of my pstat module (the one with this code), it works but spawns a second window. Is there a way I can tell this decorator about base as it is being ‘compiled’ for import?

The decorator doesn’t actually need ShowBase, it just needs some place to store its global PStatCollectors. Rewrite the decorator to replace the reference to “base” with the reference to some symbol of your choosing, which you can explicitly import from some other file that you define. Then import it within the decorator.

Actually, all this work is kind of silly. There’s no reason to unify all of the PStatCollector objects by name, and no need for a global table to manage this. (The PStatCollectors internally already unify themselves by name, so this effort is redundant.) Just replace all this nonsense with a “pstat = PStatCollector(collectorName)” and be done with it.

David