This is an offshoot of my previous thread regarding DirectEntry and events–in short, while the problem that I was encountering there seems to be solved, the lack of certain events is still causing a problem, and I’m not convinced that the issue stems from DirectEntry.
In short, under certain circumstances–I think related to the stashing and un-stashing of certain MouseWatcher nodes–I seem to lose arrow-key-related “down”-events until I press the key in question a second time.
And I do seem to be losing the events themselves: I have some calls to “accept” tying events to a specific method, and that method doesn’t appear to be fired in the case of the “missing” events. Further, previous testing with a call to “messenger.toggleVerbose” showed that the events in question weren’t showing up.
As I’ve written this, a thought has occurred to me: Could it be that, somewhere in the business of stashing and un-stashing, a previous “down”-event isn’t being marked as “completed” (or some such)?
That is, if the code run in response to a “down”-event causes the then-current MouseWatcher to be stashed and another un-stashed, could it be that the “down”-event isn’t being concluded, and that as a result it’s only after a subsequent “up”-event that a new “down”-event of that sort may be fired?
With that thought, here below is a short test-program that displays the behaviour in question on my machine.
To perform the test, run the program, and note the two displays: the top one shows a response to the “down” arrow-key, and the bottom one shows the stashing-state of the MouseWatcher.
With that in mind, press-hold-and-release the “down” arrow-key, then the “up” arrow-key, and then the “down” arrow-key again.
You should find that the last of those, the second “down” arrow-key press, should only report an “release” event, not a “press” event.
from panda3d.core import loadPrcFile, loadPrcFileData
from direct.showbase.ShowBase import ShowBase
from panda3d.core import ButtonThrower, MouseWatcher
from direct.gui.DirectGui import *
class Game(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.label1 = DirectLabel(text = "",
scale = 0.1,
pos = (0, 0, 0.25),
frameSize = (-10, 10, -2, 2))
self.label2 = DirectLabel(text = "",
scale = 0.1,
pos = (0, 0, -0.25),
frameSize = (-10, 10, -2, 2))
self.accept("arrow_down", self.keyUpdate, [1])
self.accept("arrow_down-up", self.keyUpdate, [0])
self.accept("arrow_up-up", self.resetStashing)
self.keyboardOnlyThrower = ButtonThrower("keyboardOnlyThrower")
self.keyboardOnlyWatcher = MouseWatcher("keyboardOnlyWatcher")
self.keyboardOnlyWatcher.addChild(self.keyboardOnlyThrower)
base.mouseWatcher.getParent().node().addChild(self.keyboardOnlyWatcher)
self.keyboardOnlyNodePath = self.mouseWatcher.getParent().find("keyboardOnlyWatcher")
self.keyboardOnlyNodePath.stash()
def resetStashing(self):
self.setStashState(0)
self.label1["text"] = "Key state: "
self.label1.setText()
def openDialogue(self):
self.dialogue.show()
def keyUpdate(self, state):
self.label1["text"] = "Key state: " + str(state)
self.label1.setText()
if state == 1:
self.setStashState(1)
def setStashState(self, state):
if state == 1:
if not self.mouseWatcher.isStashed():
self.mouseWatcher.stash()
self.keyboardOnlyNodePath.unstash()
self.label2["text"] = "Main watcher is STASHED"
else:
if self.mouseWatcher.isStashed():
self.mouseWatcher.unstash()
self.keyboardOnlyNodePath.stash()
self.label2["text"] = "Main watcher is UN-stashed"
app = Game()
app.run()
Interestingly, the problem doesn’t seem to occur if I instead use “raw” events, which does at least provide a workaround.
So, I suppose that my question is this: If it is as I guess, how might I (perhaps manually) “conclude” the relevant “down” events so that they might be fired again?