Panda3d 1.11 not running taskMgr.step()

I am currently making a panda3d game and I am integrating the ShowBase into a window container within PyQT. I want to use 1.11 in order to be able to use CollisionHeightField, but it seems that whenever I try to run my program, it gets stuck in the update function calling taskMgr.step() and isn’t being able to get past it.
This is how I’m calling the update() script:

self.panda_timer = QtCore.QTimer()
self.panda_timer.timeout.connect(self.update)
self.panda_timer.start(1)

This is the update script:

    def update(self):
        # dt = Delta Time: the amount of time elapsed during the task's previous run cycle in seconds
        print("update")
        dt = globalClock.getDt()
        if dt < 0.1:
            if self.cam_locked:
                self.player.update(self.keyMap,True)
            else:
                self.player.update(self.keyMap, False)
            self.terrain.update()
            self.AIWorld.update()
            self.enemyList.updateEnemies()
            self.cTrav.traverse(render)
            self.staminaBar["value"] = (self.player.stamina / self.player.max_stamina) * 100
        if self.inventory.inventoryChangedForDirect:
            self.updateHotBar()
        print("step")
        self.taskMgr.step()
        print("stepped")

And this is the output:

AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 48000hz instead
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
:display:windisplay(warning): SetForegroundWindow() failed!
update
step

Does anyone know why this could be happening?
I’ve tried running it in 1.10.15 and it runs perfectly fine

(This is before I’ve integrated anything 1.11 related)

Update: I might have a possible root cause of the issue while modifying the step() function to try to narrow down the problem:

    def step(self) -> None:
        """Invokes the task manager for one frame, and then returns.
        Normally, this executes each task exactly once, though task
        chains that are in sub-threads or that have frame budgets
        might execute their tasks differently. """

        startFrameTime = self.globalClock.getRealTime()

        # Replace keyboard interrupt handler during task list processing
        # so we catch the keyboard interrupt but don't handle it until
        # after task list processing is complete.
        self.fKeyboardInterrupt = False
        self.interruptCount = 0
        print("test1")
        if signal:
            self.__prevHandler = signal.signal(signal.SIGINT, self.keyboardInterruptHandler)
        print("test2")
        try:
            print("test3.1")
            self.mgr.poll()
            print("test3.2")
            # This is the spot for an internal yield function
            nextTaskTime = self.mgr.getNextWakeTime()
            print("test3.3")
            self.doYield(startFrameTime, nextTaskTime)
            print("test3.4")
        finally:
            # Restore previous interrupt handler
            if signal:
                signal.signal(signal.SIGINT, self.__prevHandler)
                self.__prevHandler = signal.default_int_handler

        if self.fKeyboardInterrupt:
            raise KeyboardInterrupt

And the output looks like so:

AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 48000hz instead
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
:display:windisplay(warning): SetForegroundWindow() failed!
update
step
test1
test2
test3.1

Hoping this helps!

Hi, welcome to the community!

It’s hard to say with just the information provided. Could you maybe give me a simple but complete program I can run on my computer so that I can reproduce the issue and hook in a C++ debugger?

Thank you!

It seems I have found the issue. I was recreating a simpler case and it seemed to work well so I went and looked back at previous lines I’ve written and noticed that I was double calling start() in the initialization of the game when running two threads for loading different parts of terrain. I’m assuming this might’ve caused some internal error and stopped the poll() function from working. After changing one of the start()'s to run() the program runs as expected.

The theory still holds that the double start() setup is able to run in 1.10.15 though (not in a test script). However, after some more testing it seems that it’s also able to work in 1.11 under lighter load in a test setup, but simply in my script it doesn’t? The only real reason I can attribute this to is computer load, but other than that I’m not sure why this phenomena could be happening. I can upload all the scripts to a github repository and send it, although I’m not sure how useful the outputs will be.

1 Like

It’s hard to say without seeing a full backtrace, sorry. The poll() method itself hasn’t changed much recently, it has to be something deeper within Panda’s internals that deadlocks or something like that. In any case, I’m glad you figured out a solution.

2 Likes