Author Topic: Event handlers firing multiple times?  (Read 1796 times)

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Event handlers firing multiple times?
« on: July 16, 2012, 08:51:04 PM »
Why is it that in Bridge Commander the python event handlers I set up fire multiple times for just one happening of the event ingame.

A perfect example of this could be say CTRL+SHIFT+K or CTRL+SHIFT+G but i've found all of the event handlers are guilty.

If I setup a handler and define it like so:
Code: [Select]
def GodModeOn(pObject, pEvent):
print "God mode handler triggered"
        pObject.CallNextHandler(pEvent)

def init():
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_INPUT_DEBUG_GOD_MODE, pMission, __name__ + ".GodModeOn")

I will see something like:
Quote
God mode handler triggered
God mode handler triggered
God mode handler triggered
God mode handler triggered
God mode handler triggered
in the log file for every single press of CTRL+SHIFT+G.

Why is it that this happens and how can I avoid it; have the handler triggered once per event?
Great men are not peacemakers! Great men are conquerors!

Offline JimmyB76

  • Posts: 6423
  • Cookies: 421
Re: Event handlers firing multiple times?
« Reply #1 on: July 16, 2012, 09:03:27 PM »
god mode is just SHIFT+G, not CTRL+SHIFT+G

the only time CTRL+SHIFT is used is when using Q for 10 more quantum torps..

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Event handlers firing multiple times?
« Reply #2 on: July 16, 2012, 09:36:59 PM »
Well either way regardless of the keys handlers still fire lots of times for one occurance of an event.

Subsystem disabled =
Log:
Subsystem disabled
Subsystem disabled
Subsystem disabled
Subsystem disabled
Subsystem disabled
Subsystem disabled

 :hithead:
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: Event handlers firing multiple times?
« Reply #3 on: July 17, 2012, 03:20:32 AM »
The longer you press the keys the more messages you get.
That way you can detect if a key is kept pressed, like it is used on primary fire.

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Event handlers firing multiple times?
« Reply #4 on: July 17, 2012, 11:03:53 AM »
The longer you press the keys the more messages you get.
That way you can detect if a key is kept pressed, like it is used on primary fire.
That's interesting, but how would one go about only acting on the first call and ignoring all subsequent calls. I just tried hitting SHIFT+R once as fast as I could and predicatably obviously the handler fired at least four or five times.

There has to be a better way than going out of my way to create elaborate functions such as the one below just so the handler fires once instead of a bagillion times. How'd Totally Games do it? I mean I can't find where the functions are that get called for events such as SHIFT+G or any of the other one-time user triggered keyboard events :doh:

Code: [Select]
# check if ShipInstaRepair() has already ran
def InstaRepairAlreadyRan(pShip, opObjID=None):
shipID = pShip.GetObjID()
ShieldGenerators = GetAllShieldGenerators(pShip)
# checking if both generators are operational
if ShieldGenerators[0].IsDisabled() or ShieldGenerators[1].IsDisabled():
return 0
else:
# are all shields at full strength
lShields = GetPrimarySecondaryGenNames(pShip)
pPrimaryGen = MissionLib.GetSubsystemByName(pShip, lShields[0])
pSecondaryGen = MissionLib.GetSubsystemByName(pShip, lShields[1])
pPrimaryGen = App.ShieldClass_Cast(pPrimaryGen)
pSecondaryGen = App.ShieldClass_Cast(pSecondaryGen)
i = 0
while(i < 6):
if not shipShieldVals[shipID][0][i] == pPrimaryGen.GetMaxShields(i):
return 0
if not shipShieldVals[shipID][1][i] == pSecondaryGen.GetMaxShields(i):
return 0
i = i + 1
# bugfix: return 0 so SubsystemOperational() will redefine the generators even if the operational generator was  a CTRL+SHIFT+K victim
if ctrlShiftKGenVictims.has_key(shipID):
if opObjID==None:
print "There is no opObjID"
print "ctrlShiftKGenVictim ship key ", shipID, " removed from ctrlShiftKGenVictims"
del ctrlShiftKGenVictims[shipID]
return 0
else:
if opObjID in ctrlShiftKGenVictims[shipID]:
# function was called by SubsystemOperational()
print ">>>>>>>>>>>>>opObjID is ", opObjID
print "ctrlShiftKGenVictim ship key ", shipID, " removed from ctrlShiftKGenVictims"
del ctrlShiftKGenVictims[shipID]
return 0
else:
print "Ship does NOT have a ctrlShiftKVictim generator"
print "ctrlShiftKGenVictims contents: ", ctrlShiftKGenVictims
return 1
^ Seriously, I made all of that *just* so the handler wouldn't do the same thing five or six times for every one press of the key  :(
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2200
  • Cookies: 1707
  • Life is life
Re: Event handlers firing multiple times?
« Reply #5 on: July 17, 2012, 12:02:17 PM »
If you've ever developed a WinForms app or Web app you're probably familiar with KeyUp, KeyDown events...

This would be the BC equivalent for GodMode KeyUp for example (bear in mind this is just a code snippet):

1. Setup keyboard handler
Code: [Select]
topWindow = App.TopWindow_GetTopWindow()
topWindow.AddPythonFuncHandlerForInstance(App.ET_KEYBOARD, __name__ + ".HandleKeyboard")

2. Handle event
Code: [Select]
def HandleKeyboard(pObject, pEvent):
charType = pEvent.GetUnicode()
keyType = pEvent.GetKeyState()
if charType == App.g_kKeyboardBinding.FindKey(App.ET_INPUT_DEBUG_GOD_MODE, App.KeyboardBinding.GET_EVENT, 0.0):
if (keyType == App.TGKeyboardEvent.KS_KEYUP and App.TopWindow_GetTopWindow().IsTacticalVisible()): # App.TopWindow_GetTopWindow().IsTacticalVisible() because we can only trigger god mode while in tactical view
print 'key up'
        pObject.CallNextHandler(pEvent)
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Event handlers firing multiple times?
« Reply #6 on: July 17, 2012, 12:30:11 PM »
If you've ever developed a WinForms app or Web app you're probably familiar with KeyUp, KeyDown events...

This would be the BC equivalent for GodMode KeyUp for example (bear in mind this is just a code snippet):

1. Setup keyboard handler
Code: [Select]
topWindow = App.TopWindow_GetTopWindow()
topWindow.AddPythonFuncHandlerForInstance(App.ET_KEYBOARD, __name__ + ".HandleKeyboard")

2. Handle event
Code: [Select]
def HandleKeyboard(pObject, pEvent):
charType = pEvent.GetUnicode()
keyType = pEvent.GetKeyState()
if charType == App.g_kKeyboardBinding.FindKey(App.ET_INPUT_DEBUG_GOD_MODE, App.KeyboardBinding.GET_EVENT, 0.0):
if (keyType == App.TGKeyboardEvent.KS_KEYUP and App.TopWindow_GetTopWindow().IsTacticalVisible()): # App.TopWindow_GetTopWindow().IsTacticalVisible() because we can only trigger god mode while in tactical view
print 'key up'
        pObject.CallNextHandler(pEvent)
I've got meager experience in messing around with JavaScript and VB in the past so i've come across KeyUp and KeyDown events. I could probably implement this new method of handling but the sad thing is i've spent so much time on the script and got it to run with the handlers/configurations it'd probably be more effort than it's worth to change things now that i've gone out of my way to make functions like InstaRepairAlreadyRan()  :(

I'll deffinitely remember about KeyUp/Down etc handlers in the future and hopefully avoid having to make functions just to check if a handler has already ran.
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2200
  • Cookies: 1707
  • Life is life
Re: Event handlers firing multiple times?
« Reply #7 on: July 17, 2012, 12:51:55 PM »
That is your right and choice :)

Though honestly I'd feel the same as you.
Acta, non verba.
aka USS Sovereign