<commit_before>"""Undocumented Module"""

__all__ = ['ShowBase', 'WindowControls']

# This module redefines the builtin import function with one
# that prints out every import it does in a hierarchical form
# Annoying and very noisy, but sometimes useful
#import VerboseImport

from pandac.PandaModules import *

# This needs to be available early for DirectGUI imports
__builtins__["config"] = ConfigConfigureGetConfigConfigShowbase

from direct.directnotify.DirectNotifyGlobal import *
from MessengerGlobal import *
from BulletinBoardGlobal import *
from direct.task.TaskManagerGlobal import *
from EventManagerGlobal import *
from PythonUtil import *
from direct.particles.ParticleManagerGlobal import *
from PhysicsManagerGlobal import *
#from direct.interval.IntervalManager import ivalMgr
from direct.interval import IntervalManager
from InputStateGlobal import inputState
from direct.showbase.BufferViewer import BufferViewer
from direct.task import Task
from direct.directutil import Verify
import EventManager
import math
import sys
import Loader
import time
from direct.fsm import ClassicFSM
from direct.fsm import State
import DirectObject
import SfxPlayer
if __debug__:
    from direct.directutil import DeltaProfiler
import OnScreenDebug

__builtins__["FADE_SORT_INDEX"] = 1000
__builtins__["NO_FADE_SORT_INDEX"] = 2000

# Now ShowBase is a DirectObject.  We need this so ShowBase can hang
# hooks on messages, particularly on window-event.  This doesn't
# *seem* to cause anyone any problems.
class ShowBase(DirectObject.DirectObject):

    notify = directNotify.newCategory("ShowBase")

    def __init__(self):
        # Get the dconfig object
        #self.config = ConfigConfigureGetConfigConfigShowbase
        self.config = config
        # Setup wantVerifyPdb as soon as reasonable:
        Verify.wantVerifyPdb = self.config.GetBool('want-verify-pdb', 0)

        self.printEnvDebugInfo()
        vfs = VirtualFileSystem.getGlobalPtr()

        self.nextWindowIndex = 1

        # Store dconfig variables
        self.sfxActive = self.config.GetBool('audio-sfx-active', 1)
        self.musicActive = self.config.GetBool('audio-music-active', 1)
        self.wantFog = self.config.GetBool('want-fog', 1)
        self.wantRender2dp = self.config.GetBool('want-render2dp', 1)

        self.screenshotExtension = self.config.GetString('screenshot-extension', 'jpg')
        self.musicManager = None
        self.musicManagerIsValid = None
        self.sfxManagerList = []
        self.sfxManagerIsValidList = []

        self.wantStats = self.config.GetBool('want-pstats', 0)

        # Fill this in with a function to invoke when the user "exits"
        # the program by closing the main window.
        self.exitFunc = None

        Task.TaskManager.taskTimerVerbose = self.config.GetBool('task-timer-verbose', 0)
        Task.TaskManager.extendedExceptions = self.config.GetBool('extended-exceptions', 0)
        Task.TaskManager.pStatsTasks = self.config.GetBool('pstats-tasks', 0)

        # Set up the TaskManager to reset the PStats clock back
        # whenever we resume from a pause.  This callback function is
        # a little hacky, but we can't call it directly from within
        # the TaskManager because he doesn't know about PStats (and
        # has to run before libpanda is even loaded).
        taskMgr.resumeFunc = PStatClient.resumeAfterPause

        # If the aspect ratio is 0 or None, it means to infer the
        # aspect ratio from the window size.
        # If you need to know the actual aspect ratio call base.getAspectRatio()
        self.__configAspectRatio = ConfigVariableDouble('aspect-ratio', 0).getValue()
        # This variable is used to see if the aspect ratio has changed when
        # we get a window-event.
        self.__oldAspectRatio = None

        self.windowType = self.config.GetString('window-type', 'onscreen')
        self.requireWindow = self.config.GetBool('require-window', 1)

        # base.win is the main, or only window; base.winList is a list of
        # *all* windows.  Similarly with base.camList.
        self.win = None
        self.frameRateMeter = None
        self.winList = []
        self.winControls = []
        self.mainWinMinimized = 0
        self.pipe = None
        self.pipeList = []
        self.mouse2cam = None
        self.buttonThrowers = None
        self.mouseWatcher = None
        self.mouseWatcherNode = None
        self.pointerWatcherNodes = None
        self.mouseInterface = None
        self.drive = None
        self.trackball = None
        self.cam = None
        self.cam2d = None
        self.cam2dp = None
        self.camera = None
        self.camera2d = None
        self.camera2dp = None
        self.camList = []
        self.camNode = None
        self.camLens = None
        self.camFrustumVis = None

        # This is used for syncing multiple PCs in a distributed cluster
        try:
            # Has the cluster sync variable been set externally?
            self.clusterSyncFlag = clusterSyncFlag
        except NameError:
            # Has the clusterSyncFlag been set via a config variable
            self.clusterSyncFlag = self.config.GetBool('cluster-sync', 0)

        self.hidden = NodePath('hidden')

        # We need a graphics engine to manage the actual rendering.
        self.graphicsEngine = GraphicsEngine()

        self.setupRender()
        self.setupRender2d()
        self.setupDataGraph()

        if self.wantRender2dp:
            self.setupRender2dp()


        # This is a placeholder for a CollisionTraverser.  If someone
        # stores a CollisionTraverser pointer here, we'll traverse it
        # in the collisionLoop task.
        self.shadowTrav = 0
        # in the collisionLoop task.
        self.cTrav = 0
        self.cTravStack = Stack()
        # Ditto for an AppTraverser.
        self.appTrav = 0

        # This is the DataGraph traverser, which we might as well
        # create now.
        self.dgTrav = DataGraphTraverser()

        # Maybe create a RecorderController to record and/or play back
        # the user session.
        self.recorder = None
        playbackSession = self.config.GetString('playback-session', '')
        recordSession = self.config.GetString('record-session', '')
        if playbackSession:
            self.recorder = RecorderController()
            self.recorder.beginPlayback(Filename.fromOsSpecific(playbackSession))
        elif recordSession:
            self.recorder = RecorderController()
            self.recorder.beginRecord(Filename.fromOsSpecific(recordSession))

        if self.recorder:
            # If we're either playing back or recording, pass the
            # random seed into the system so each session will have
            # the same random seed.
            import random, whrandom

            seed = self.recorder.getRandomSeed()
            random.seed(seed)
            whrandom.seed(seed & 0xff, (seed >> 8) & 0xff, (seed >> 16) & 0xff)

        # Now that we've set up the window structures, assign an exitfunc.
        self.oldexitfunc = getattr(sys, 'exitfunc', None)
        sys.exitfunc = self.exitfunc

        # Open the default rendering window.
        if self.windowType != 'none':
            self.openDefaultWindow()

        self.loader = Loader.Loader(self)
        self.eventMgr = eventMgr
        self.messenger = messenger
        self.bboard = bulletinBoard
        self.taskMgr = taskMgr

        # Particle manager
        self.particleMgr = particleMgr
        self.particleMgr.setFrameStepping(1)
        self.particleMgrEnabled = 0

        # Physics manager
        self.physicsMgr = physicsMgr
        integrator = LinearEulerIntegrator()
        self.physicsMgr.attachLinearIntegrator(integrator)
        self.physicsMgrEnabled = 0
        self.physicsMgrAngular = 0

        self.createBaseAudioManagers()
        self.createStats()

        self.AppHasAudioFocus = 1

        # Get a pointer to Panda's global ClockObject, used for
        # synchronizing events between Python and C.
        # object is exactly in sync with the TrueClock.
        globalClock = ClockObject.getGlobalClock()

        # Since we have already started up a TaskManager, and probably
        # a number of tasks; and since the TaskManager had to use the
        # TrueClock to tell time until this moment, make sure the
        # globalClock
        trueClock = TrueClock.getGlobalPtr()
        globalClock.setRealTime(trueClock.getShortTime())
        globalClock.tick()

        # Now we can make the TaskManager start using the new globalClock.
        taskMgr.globalClock = globalClock

        __builtins__["base"] = self
        __builtins__["render2d"] = self.render2d
        __builtins__["aspect2d"] = self.aspect2d
        __builtins__["render"] = self.render
        __builtins__["hidden"] = self.hidden
        __builtins__["camera"] = self.camera
        __builtins__["loader"] = self.loader
        __builtins__["taskMgr"] = self.taskMgr
        __builtins__["eventMgr"] = self.eventMgr
        __builtins__["messenger"] = self.messenger
        __builtins__["bboard"] = self.bboard
        # Config needs to be defined before ShowBase is constructed
        #__builtins__["config"] = self.config
        __builtins__["run"] = self.run
        __builtins__["ostream"] = Notify.out()
        __builtins__["directNotify"] = directNotify
        __builtins__["giveNotify"] = giveNotify
        __builtins__["globalClock"] = globalClock
        __builtins__["vfs"] = vfs
        __builtins__["cpMgr"] = ConfigPageManager.getGlobalPtr()
        __builtins__["cvMgr"] = ConfigVariableManager.getGlobalPtr()
        __builtins__["pandaSystem"] = PandaSystem.getGlobalPtr()
        __builtins__["__dev__"] = base.config.GetBool('want-dev', 0)
        __builtins__["wantUberdog"] = base.config.GetBool('want-uberdog', 1)
        if __debug__:
            __builtins__["deltaProfiler"] = DeltaProfiler.DeltaProfiler("ShowBase")
        __builtins__["onScreenDebug"] = OnScreenDebug.OnScreenDebug()

        if self.wantRender2dp:
            __builtins__["render2dp"] = self.render2dp
            __builtins__["aspect2dp"] = self.aspect2dp

        ShowBase.notify.info('__dev__ == %s' % __dev__)

        if __dev__ or self.config.GetBool('want-e3-hacks', False):
            if self.config.GetBool('track-gui-items', True):
                # dict of guiId to gui item, for tracking down leaks
                self.guiItems = {}

        # 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.accept('window-event', self.__windowEvent)

        # Transition effects (fade, iris, etc)
        import Transitions
        self.transitions = Transitions.Transitions(self.loader)

        # Setup the window controls - handy for multiwindow applications
        self.setupWindowControls()

        # Client sleep
        sleepTime = self.config.GetFloat('client-sleep', 0.0)
        self.clientSleep = 0.0
        self.setSleep(sleepTime)
        
        # Extra sleep for running 4+ clients on a single machine
        # adds a sleep right after the main render in igloop
        # tends to even out the frame rate and keeps it from going
        # to zero in the out of focus windows
        if base.config.GetBool('multi-sleep', 1):
            self.multiClientSleep = 1
        else:
            self.multiClientSleep = 0

        # Offscreen buffer viewing utility.
        # This needs to be allocated even if the viewer is off.
        self.bufferViewer = BufferViewer()

        # Start Tk and DIRECT if specified by Config.prc
        fTk = self.config.GetBool('want-tk', 0)
        # Start DIRECT if specified in Config.prc or in cluster mode
        fDirect = (self.config.GetBool('want-directtools', 0) or
                   (base.config.GetString("cluster-mode", '') != ''))
        # Set fWantTk to 0 to avoid starting Tk with this call
        self.startDirect(fWantDirect = fDirect, fWantTk = fTk)
        # Start IGLOOP
        self.restart()

    # add a collision traverser via pushCTrav and remove it via popCTrav
    # that way the owner of the new cTrav doesn't need to hold onto the
    # previous one in order to put it back
    def pushCTrav(self, cTrav):
        self.cTravStack.push(self.cTrav)
        self.cTrav = cTrav
    def popCTrav(self):
        self.cTrav = self.cTravStack.pop()

    def printEnvDebugInfo(self):
        """
        Print some information about the environment that we are running
        in.  Stuff like the model paths and other paths.  Feel free to
        add stuff to this.
        """
        if self.config.GetBool('want-env-debug-info', 0):
           print "\n\nEnvironment Debug Info {"
           print "* model path:"
           print getModelPath()
           #print "* dna path:"
           #print getDnaPath()
           print "* texture path:"
           print getTexturePath()
           print "* sound path:"
           print getSoundPath()
           print "}"

    def exitfunc(self):
        """
        This should be assigned to sys.exitfunc to be called just
        before Python shutdown.  It guarantees that the Panda window
        is closed cleanly, so that we free system resources, restore
        the desktop and keyboard functionality, etc.
        """
        self.graphicsEngine.removeAllWindows()

        if self.musicManager:
            self.musicManager.shutdown()

        del self.win
        del self.winList
        del self.pipe
        del self.musicManager
        del self.sfxManagerList

        try:
            base.direct.panel.destroy()
        except StandardError:
            pass

        if self.oldexitfunc:
            self.oldexitfunc()

    def makeDefaultPipe(self):
        """
        Creates the default GraphicsPipe, which will be used to make
        windows unless otherwise specified.
        """
        assert self.pipe == None
        selection = GraphicsPipeSelection.getGlobalPtr()
        selection.printPipeTypes()
        self.pipe = selection.makeDefaultPipe()
        if not self.pipe:
            self.notify.error(
                "No graphics pipe is available!\n"
                "Your Config.prc file must name at least one valid panda display\n"
                "library via load-display or aux-display.")

        self.notify.info("Default graphics pipe is %s (%s)." % (
            self.pipe.getInterfaceName(), self.pipe.getType().getName()))
        self.pipeList.append(self.pipe)

    def makeAllPipes(self):
        """
        Creates all GraphicsPipes that the system knows about and fill up
        self.pipeList with them.
        """
        shouldPrintPipes = 0
        selection = GraphicsPipeSelection.getGlobalPtr()
        selection.loadAuxModules()

        # First, we should make sure the default pipe exists.
        if self.pipe == None:
            self.makeDefaultPipe()

        # Now go through the list of known pipes, and make each one if
        # we don't have one already.
        numPipeTypes = selection.getNumPipeTypes()
        for i in range(numPipeTypes):
            pipeType = selection.getPipeType(i)

            # Do we already have a pipe of this type on the list?
            # This operation is n-squared, but presumably there won't
            # be more than a handful of pipe types, so who cares.
            already = 0
            for pipe in self.pipeList:
                if pipe.getType() == pipeType:
                    already = 1

            if not already:
                pipe = selection.makePipe(pipeType)
                if pipe:
                    self.notify.info("Got aux graphics pipe %s (%s)." % (
                        pipe.getInterfaceName(), pipe.getType().getName()))
                    self.pipeList.append(pipe)
                else:
                    self.notify.info("Could not make graphics pipe %s." % (
                        pipeType.getName()))

    def openWindow(self, props = None, pipe = None, gsg = None,
                   type = None, name = None, size = None, aspectRatio = None,
                   makeCamera = 1, scene = None, stereo = None):
        """
        Creates a window and adds it to the list of windows that are
        to be updated every frame.
        """
        if pipe == None:
            pipe = self.pipe

            if pipe == None:
                self.makeDefaultPipe()
                pipe = self.pipe

            if pipe == None:
                # We couldn't get a pipe.
                return None

        if type == None:
            type = self.windowType

        if props == None:
            props = WindowProperties.getDefault()

        if size != None:
            # If we were given an explicit size, use it; otherwise,
            # the size from the properties is used.
            props = WindowProperties(props)
            props.setSize(size[0], size[1])

        if name == None:
            name = 'window%s' % (self.nextWindowIndex)
            self.nextWindowIndex += 1

        win = None

        fbprops = FrameBufferProperties.getDefault()

        flags = GraphicsPipe.BFFbPropsOptional
        if type == 'onscreen':
            flags = flags | GraphicsPipe.BFRequireWindow
        elif type == 'offscreen':
            flags = flags | GraphicsPipe.BFRefuseWindow

        if gsg:
            win = self.graphicsEngine.makeOutput(pipe, name, 0, fbprops,
                                                 props, flags, gsg)
        else:
            win = self.graphicsEngine.makeOutput(pipe, name, 0, fbprops,
                                                 props, flags)

        if win == None:
            # Couldn't create a window!
            return None

        if hasattr(win, "requestProperties"):
            win.requestProperties(props)

        if self.win == None:
            self.win = win

        self.winList.append(win)

        # Set up a 3-d camera for the window by default.
        if makeCamera:
            self.makeCamera(win, scene = scene, aspectRatio = aspectRatio,
                            stereo = stereo)

        return win

    def closeWindow(self, win):
        """
        Closes the indicated window and removes it from the list of<commit_msg>Do not reuse gsg.   This fixes fullscreen/window display switching problems.<commit_after>"""Undocumented Module"""

__all__ = ['ShowBase', 'WindowControls']

# This module redefines the builtin import function with one
# that prints out every import it does in a hierarchical form
# Annoying and very noisy, but sometimes useful
#import VerboseImport

from pandac.PandaModules import *

# This needs to be available early for DirectGUI imports
__builtins__["config"] = ConfigConfigureGetConfigConfigShowbase

from direct.directnotify.DirectNotifyGlobal import *
from MessengerGlobal import *
from BulletinBoardGlobal import *
from direct.task.TaskManagerGlobal import *
from EventManagerGlobal import *
from PythonUtil import *
from direct.particles.ParticleManagerGlobal import *
from PhysicsManagerGlobal import *
#from direct.interval.IntervalManager import ivalMgr
from direct.interval import IntervalManager
from InputStateGlobal import inputState
from direct.showbase.BufferViewer import BufferViewer
from direct.task import Task
from direct.directutil import Verify
import EventManager
import math
import sys
import Loader
import time
from direct.fsm import ClassicFSM
from direct.fsm import State
import DirectObject
import SfxPlayer
if __debug__:
    from direct.directutil import DeltaProfiler
import OnScreenDebug

__builtins__["FADE_SORT_INDEX"] = 1000
__builtins__["NO_FADE_SORT_INDEX"] = 2000

# Now ShowBase is a DirectObject.  We need this so ShowBase can hang
# hooks on messages, particularly on window-event.  This doesn't
# *seem* to cause anyone any problems.
class ShowBase(DirectObject.DirectObject):

    notify = directNotify.newCategory("ShowBase")

    def __init__(self):
        # Get the dconfig object
        #self.config = ConfigConfigureGetConfigConfigShowbase
        self.config = config
        # Setup wantVerifyPdb as soon as reasonable:
        Verify.wantVerifyPdb = self.config.GetBool('want-verify-pdb', 0)

        self.printEnvDebugInfo()
        vfs = VirtualFileSystem.getGlobalPtr()

        self.nextWindowIndex = 1

        # Store dconfig variables
        self.sfxActive = self.config.GetBool('audio-sfx-active', 1)
        self.musicActive = self.config.GetBool('audio-music-active', 1)
        self.wantFog = self.config.GetBool('want-fog', 1)
        self.wantRender2dp = self.config.GetBool('want-render2dp', 1)

        self.screenshotExtension = self.config.GetString('screenshot-extension', 'jpg')
        self.musicManager = None
        self.musicManagerIsValid = None
        self.sfxManagerList = []
        self.sfxManagerIsValidList = []

        self.wantStats = self.config.GetBool('want-pstats', 0)

        # Fill this in with a function to invoke when the user "exits"
        # the program by closing the main window.
        self.exitFunc = None

        Task.TaskManager.taskTimerVerbose = self.config.GetBool('task-timer-verbose', 0)
        Task.TaskManager.extendedExceptions = self.config.GetBool('extended-exceptions', 0)
        Task.TaskManager.pStatsTasks = self.config.GetBool('pstats-tasks', 0)

        # Set up the TaskManager to reset the PStats clock back
        # whenever we resume from a pause.  This callback function is
        # a little hacky, but we can't call it directly from within
        # the TaskManager because he doesn't know about PStats (and
        # has to run before libpanda is even loaded).
        taskMgr.resumeFunc = PStatClient.resumeAfterPause

        # If the aspect ratio is 0 or None, it means to infer the
        # aspect ratio from the window size.
        # If you need to know the actual aspect ratio call base.getAspectRatio()
        self.__configAspectRatio = ConfigVariableDouble('aspect-ratio', 0).getValue()
        # This variable is used to see if the aspect ratio has changed when
        # we get a window-event.
        self.__oldAspectRatio = None

        self.windowType = self.config.GetString('window-type', 'onscreen')
        self.requireWindow = self.config.GetBool('require-window', 1)

        # base.win is the main, or only window; base.winList is a list of
        # *all* windows.  Similarly with base.camList.
        self.win = None
        self.frameRateMeter = None
        self.winList = []
        self.winControls = []
        self.mainWinMinimized = 0
        self.pipe = None
        self.pipeList = []
        self.mouse2cam = None
        self.buttonThrowers = None
        self.mouseWatcher = None
        self.mouseWatcherNode = None
        self.pointerWatcherNodes = None
        self.mouseInterface = None
        self.drive = None
        self.trackball = None
        self.cam = None
        self.cam2d = None
        self.cam2dp = None
        self.camera = None
        self.camera2d = None
        self.camera2dp = None
        self.camList = []
        self.camNode = None
        self.camLens = None
        self.camFrustumVis = None

        # This is used for syncing multiple PCs in a distributed cluster
        try:
            # Has the cluster sync variable been set externally?
            self.clusterSyncFlag = clusterSyncFlag
        except NameError:
            # Has the clusterSyncFlag been set via a config variable
            self.clusterSyncFlag = self.config.GetBool('cluster-sync', 0)

        self.hidden = NodePath('hidden')

        # We need a graphics engine to manage the actual rendering.
        self.graphicsEngine = GraphicsEngine()

        self.setupRender()
        self.setupRender2d()
        self.setupDataGraph()

        if self.wantRender2dp:
            self.setupRender2dp()


        # This is a placeholder for a CollisionTraverser.  If someone
        # stores a CollisionTraverser pointer here, we'll traverse it
        # in the collisionLoop task.
        self.shadowTrav = 0
        # in the collisionLoop task.
        self.cTrav = 0
        self.cTravStack = Stack()
        # Ditto for an AppTraverser.
        self.appTrav = 0

        # This is the DataGraph traverser, which we might as well
        # create now.
        self.dgTrav = DataGraphTraverser()

        # Maybe create a RecorderController to record and/or play back
        # the user session.
        self.recorder = None
        playbackSession = self.config.GetString('playback-session', '')
        recordSession = self.config.GetString('record-session', '')
        if playbackSession:
            self.recorder = RecorderController()
            self.recorder.beginPlayback(Filename.fromOsSpecific(playbackSession))
        elif recordSession:
            self.recorder = RecorderController()
            self.recorder.beginRecord(Filename.fromOsSpecific(recordSession))

        if self.recorder:
            # If we're either playing back or recording, pass the
            # random seed into the system so each session will have
            # the same random seed.
            import random, whrandom

            seed = self.recorder.getRandomSeed()
            random.seed(seed)
            whrandom.seed(seed & 0xff, (seed >> 8) & 0xff, (seed >> 16) & 0xff)

        # Now that we've set up the window structures, assign an exitfunc.
        self.oldexitfunc = getattr(sys, 'exitfunc', None)
        sys.exitfunc = self.exitfunc

        # Open the default rendering window.
        if self.windowType != 'none':
            self.openDefaultWindow()

        self.loader = Loader.Loader(self)
        self.eventMgr = eventMgr
        self.messenger = messenger
        self.bboard = bulletinBoard
        self.taskMgr = taskMgr

        # Particle manager
        self.particleMgr = particleMgr
        self.particleMgr.setFrameStepping(1)
        self.particleMgrEnabled = 0

        # Physics manager
        self.physicsMgr = physicsMgr
        integrator = LinearEulerIntegrator()
        self.physicsMgr.attachLinearIntegrator(integrator)
        self.physicsMgrEnabled = 0
        self.physicsMgrAngular = 0

        self.createBaseAudioManagers()
        self.createStats()

        self.AppHasAudioFocus = 1

        # Get a pointer to Panda's global ClockObject, used for
        # synchronizing events between Python and C.
        # object is exactly in sync with the TrueClock.
        globalClock = ClockObject.getGlobalClock()

        # Since we have already started up a TaskManager, and probably
        # a number of tasks; and since the TaskManager had to use the
        # TrueClock to tell time until this moment, make sure the
        # globalClock
        trueClock = TrueClock.getGlobalPtr()
        globalClock.setRealTime(trueClock.getShortTime())
        globalClock.tick()

        # Now we can make the TaskManager start using the new globalClock.
        taskMgr.globalClock = globalClock

        __builtins__["base"] = self
        __builtins__["render2d"] = self.render2d
        __builtins__["aspect2d"] = self.aspect2d
        __builtins__["render"] = self.render
        __builtins__["hidden"] = self.hidden
        __builtins__["camera"] = self.camera
        __builtins__["loader"] = self.loader
        __builtins__["taskMgr"] = self.taskMgr
        __builtins__["eventMgr"] = self.eventMgr
        __builtins__["messenger"] = self.messenger
        __builtins__["bboard"] = self.bboard
        # Config needs to be defined before ShowBase is constructed
        #__builtins__["config"] = self.config
        __builtins__["run"] = self.run
        __builtins__["ostream"] = Notify.out()
        __builtins__["directNotify"] = directNotify
        __builtins__["giveNotify"] = giveNotify
        __builtins__["globalClock"] = globalClock
        __builtins__["vfs"] = vfs
        __builtins__["cpMgr"] = ConfigPageManager.getGlobalPtr()
        __builtins__["cvMgr"] = ConfigVariableManager.getGlobalPtr()
        __builtins__["pandaSystem"] = PandaSystem.getGlobalPtr()
        __builtins__["__dev__"] = base.config.GetBool('want-dev', 0)
        __builtins__["wantUberdog"] = base.config.GetBool('want-uberdog', 1)
        if __debug__:
            __builtins__["deltaProfiler"] = DeltaProfiler.DeltaProfiler("ShowBase")
        __builtins__["onScreenDebug"] = OnScreenDebug.OnScreenDebug()

        if self.wantRender2dp:
            __builtins__["render2dp"] = self.render2dp
            __builtins__["aspect2dp"] = self.aspect2dp

        ShowBase.notify.info('__dev__ == %s' % __dev__)

        if __dev__ or self.config.GetBool('want-e3-hacks', False):
            if self.config.GetBool('track-gui-items', True):
                # dict of guiId to gui item, for tracking down leaks
                self.guiItems = {}

        # 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.accept('window-event', self.__windowEvent)

        # Transition effects (fade, iris, etc)
        import Transitions
        self.transitions = Transitions.Transitions(self.loader)

        # Setup the window controls - handy for multiwindow applications
        self.setupWindowControls()

        # Client sleep
        sleepTime = self.config.GetFloat('client-sleep', 0.0)
        self.clientSleep = 0.0
        self.setSleep(sleepTime)
        
        # Extra sleep for running 4+ clients on a single machine
        # adds a sleep right after the main render in igloop
        # tends to even out the frame rate and keeps it from going
        # to zero in the out of focus windows
        if base.config.GetBool('multi-sleep', 1):
            self.multiClientSleep = 1
        else:
            self.multiClientSleep = 0

        # Offscreen buffer viewing utility.
        # This needs to be allocated even if the viewer is off.
        self.bufferViewer = BufferViewer()

        # Start Tk and DIRECT if specified by Config.prc
        fTk = self.config.GetBool('want-tk', 0)
        # Start DIRECT if specified in Config.prc or in cluster mode
        fDirect = (self.config.GetBool('want-directtools', 0) or
                   (base.config.GetString("cluster-mode", '') != ''))
        # Set fWantTk to 0 to avoid starting Tk with this call
        self.startDirect(fWantDirect = fDirect, fWantTk = fTk)
        # Start IGLOOP
        self.restart()

    # add a collision traverser via pushCTrav and remove it via popCTrav
    # that way the owner of the new cTrav doesn't need to hold onto the
    # previous one in order to put it back
    def pushCTrav(self, cTrav):
        self.cTravStack.push(self.cTrav)
        self.cTrav = cTrav
    def popCTrav(self):
        self.cTrav = self.cTravStack.pop()

    def printEnvDebugInfo(self):
        """
        Print some information about the environment that we are running
        in.  Stuff like the model paths and other paths.  Feel free to
        add stuff to this.
        """
        if self.config.GetBool('want-env-debug-info', 0):
           print "\n\nEnvironment Debug Info {"
           print "* model path:"
           print getModelPath()
           #print "* dna path:"
           #print getDnaPath()
           print "* texture path:"
           print getTexturePath()
           print "* sound path:"
           print getSoundPath()
           print "}"

    def exitfunc(self):
        """
        This should be assigned to sys.exitfunc to be called just
        before Python shutdown.  It guarantees that the Panda window
        is closed cleanly, so that we free system resources, restore
        the desktop and keyboard functionality, etc.
        """
        self.graphicsEngine.removeAllWindows()

        if self.musicManager:
            self.musicManager.shutdown()

        del self.win
        del self.winList
        del self.pipe
        del self.musicManager
        del self.sfxManagerList

        try:
            base.direct.panel.destroy()
        except StandardError:
            pass

        if self.oldexitfunc:
            self.oldexitfunc()

    def makeDefaultPipe(self):
        """
        Creates the default GraphicsPipe, which will be used to make
        windows unless otherwise specified.
        """
        assert self.pipe == None
        selection = GraphicsPipeSelection.getGlobalPtr()
        selection.printPipeTypes()
        self.pipe = selection.makeDefaultPipe()
        if not self.pipe:
            self.notify.error(
                "No graphics pipe is available!\n"
                "Your Config.prc file must name at least one valid panda display\n"
                "library via load-display or aux-display.")

        self.notify.info("Default graphics pipe is %s (%s)." % (
            self.pipe.getInterfaceName(), self.pipe.getType().getName()))
        self.pipeList.append(self.pipe)

    def makeAllPipes(self):
        """
        Creates all GraphicsPipes that the system knows about and fill up
        self.pipeList with them.
        """
        shouldPrintPipes = 0
        selection = GraphicsPipeSelection.getGlobalPtr()
        selection.loadAuxModules()

        # First, we should make sure the default pipe exists.
        if self.pipe == None:
            self.makeDefaultPipe()

        # Now go through the list of known pipes, and make each one if
        # we don't have one already.
        numPipeTypes = selection.getNumPipeTypes()
        for i in range(numPipeTypes):
            pipeType = selection.getPipeType(i)

            # Do we already have a pipe of this type on the list?
            # This operation is n-squared, but presumably there won't
            # be more than a handful of pipe types, so who cares.
            already = 0
            for pipe in self.pipeList:
                if pipe.getType() == pipeType:
                    already = 1

            if not already:
                pipe = selection.makePipe(pipeType)
                if pipe:
                    self.notify.info("Got aux graphics pipe %s (%s)." % (
                        pipe.getInterfaceName(), pipe.getType().getName()))
                    self.pipeList.append(pipe)
                else:
                    self.notify.info("Could not make graphics pipe %s." % (
                        pipeType.getName()))

    def openWindow(self, props = None, pipe = None, gsg = None,
                   type = None, name = None, size = None, aspectRatio = None,
                   makeCamera = 1, scene = None, stereo = None):
        """
        Creates a window and adds it to the list of windows that are
        to be updated every frame.
        """
        if pipe == None:
            pipe = self.pipe

            if pipe == None:
                self.makeDefaultPipe()
                pipe = self.pipe

            if pipe == None:
                # We couldn't get a pipe.
                return None

        if type == None:
            type = self.windowType

        if props == None:
            props = WindowProperties.getDefault()

        if size != None:
            # If we were given an explicit size, use it; otherwise,
            # the size from the properties is used.
            props = WindowProperties(props)
            props.setSize(size[0], size[1])

        if name == None:
            name = 'window%s' % (self.nextWindowIndex)
            self.nextWindowIndex += 1

        win = None

        fbprops = FrameBufferProperties.getDefault()

        flags = GraphicsPipe.BFFbPropsOptional
        if type == 'onscreen':
            flags = flags | GraphicsPipe.BFRequireWindow
        elif type == 'offscreen':
            flags = flags | GraphicsPipe.BFRefuseWindow

        if gsg:
            win = self.graphicsEngine.makeOutput(pipe, name, 0, fbprops,
                                                 props, flags)
        else:
            win = self.graphicsEngine.makeOutput(pipe, name, 0, fbprops,
                                                 props, flags)

        if win == None:
            # Couldn't create a window!
            return None

        if hasattr(win, "requestProperties"):
            win.requestProperties(props)

        if self.win == None:
            self.win = win

        self.winList.append(win)

        # Set up a 3-d camera for the window by default.
        if makeCamera:
            self.makeCamera(win, scene = scene, aspectRatio = aspectRatio,
                            stereo = stereo)

        return win

    def closeWindow(self, win):
        """
        Closes the indicated window and removes it from the list of
{'fraction_non_alphanumeric': 0.08063112078346028, 'fraction_numerical': 0.0044069640914037, 'mean_word_length': 2.1527444253859347, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6622476', 'n_tokens_mistral': 10033, 'n_tokens_neox': 9710, 'n_words': 3019}