error right after DirectButton callback method [SOLVED]

hi

panda gives me an error right after processing the callback method from a DirectButton click. here’s the instanciating code for the DirectButton:

DirectButton(geom=(self.resources['h_sprinter']),borderWidth=(0,0),command=self.show_unit_conf, extraArgs='h_sprinter')

a bit later (but before any click) the button gets reparented to pixel2d.

the error I get is this one:

Traceback (most recent call last):
  File "/media/z0/python/1001/golive_client/main.py", line 140, in <module>
    taskMgr.step()
  File "/usr/share/panda3d/direct/task/Task.py", line 454, in step
    self.mgr.poll()
  File "/usr/share/panda3d/direct/showbase/EventManager.py", line 61, in eventLoopTask
    self.doEvents()
  File "/usr/share/panda3d/direct/showbase/EventManager.py", line 55, in doEvents
    processFunc(self.eventQueue.dequeueEvent())
  File "/usr/share/panda3d/direct/showbase/EventManager.py", line 124, in processEvent
    messenger.send(eventName)
  File "/usr/share/panda3d/direct/showbase/Messenger.py", line 325, in send
    self.__dispatch(acceptorDict, event, sentArgs, foundWatch)
  File "/usr/share/panda3d/direct/showbase/Messenger.py", line 410, in __dispatch
    method (*(extraArgs + sentArgs))
ValueError: list.remove(x): x not in list
:TaskManager: TaskManager.destroy()

I’ve looked up the forum for the last error lines, but I could not find any help from the results, so any suggestion is welcome :slight_smile:

edit: solved 8)

You’ll need to put the string argument in a list. Otherwise it gets interpreted as one-character arguments.

arf I am sorry, at the moment I wrote the post the code I copy-pasted did not have the extraArgs so I quickly added it on the fly, and forgot the list thing.

The actual code has the extraArgs param as a list, and produce the error after the callback to my function. Sorry for this mistake.

Something jumped out at me in the messenger.py code.

                self.lock.release()

might be trying to remove itself from something it’s not in. It occurs right above in line 408. So oddly it might be a synchro. issue.

Otherwise nothing jumps out and we can try a repro if you want.

It does seem weird. Is your handler function doing something unusual to the messenger while it is processing, like removing its own event or something? (This should be legal, but I’m trying to narrow down where to look to understand what’s going wrong.)

Or is it possible you are using threads?

David

The function doesn’t do anything yet, and I am not using threads.

If I add

self.accept('x',self.show_unit_conf,extraArgs=['v_sprinter'])

, then everything works fine, so the problem might rather come from DirectButton’s use of messenger.

I’ll be working on that in the coming hours.

Ok this is the piece of code that was eventually wrong:

class GamingCam(object,DirectObject):
	def __init__(self,...):
		self.keys_down=[]
		#...
		self.accept('mouse1',self.keys_down.append,extraArgs=['m'])
		self.accept('mouse1-up',self.keys_down.remove,extraArgs=['m'])

(the cam keep track of the mouse to move the view over the gaming board)

the problem is that when this code is used at the same time as a DirectButton, the event mouse1 is ‘consumed’ by the button before the camera, so the self.keys_down is not appended, but when the mouse is released, the cam tries to remove it anyway.

The problem is solved, but isn’t it a bit strange that the DirectButton doesn’t also catch (thus hide) the mouse1-up ?

Do I have it right, that you want to remove a button when it’s clicked?

Nope the button rest here, it is rather:
-the GamingCamera is setup to add and remove a mouse is currently pressed marker in a list (without any safety checking)
-the DirectButton hides the event mouse is pressed from the GaminCamera, but not the mouse is released one
->when the cam receives mouse is being released, it tries to remove an event that is not in its array, hence the error. The error is located in the messenger callback mechanism because the removing is done inside the button callback method:

button clicked
   messenger does the callback <--error catched
      gamingCam removes the marker <--error produced

If you want to stop the DirectButton from consuming the key, pass suppressKeys=0 to the constructor.
But if you don’t, use this for your mouse up command :
lambda a: yourList.remove(a) if a in yourList else 0