Callbacks and Refcons¶
Many functions include a “reference constant” (refCon) as an input parameter. In every case, this reference constanct can be any python object (int, float, dict, etc.) and will be passed to your callback function. If the object is mutable (e.g., dict, list), you’ll be able to change its value within, or outside of the callback and that new value will be maintained.
For mutable objects, remember you need to keep the same object, that is its id()
must not change.
That means for
dictobjects, you can:>>> refCon = {} >>> id(refCon) 15739916928 >>> refCon['a'] = 1 >>> refCon['b'] = 2 >>> refCon.update({'c': 3}) >>> refCon.pop('b') 2 >>> refCon.clear() >>> id(refCon) 15739916928
But, a new assignment changes it:
>>> refCon = {'z': 26} >>> id(refCon) 5116507392
Similarly for lists:
>>> refCon = [] >>> id(refCon) 15529489344 >>> refCon.append('world') >>> refCon.append('hello') >>> refCon.reverse() >>> refCon.remove('hello') >>> refCon.insert(0, 'Hello') >>> id(refCon) 15529489344
But, a new assignment changes it:
>>> refCon = ['new string'] >>> id(refCon) 1650739251
Passing an int, float or string variable as a reference constant does not allow
you to change it later, because any change to the variable results is a new id()
>>> refCon = 4
>>> id(refCon)
529489344
>>> refCon += 1
>>> id(refCon)
881650739
In a few cases, the reference constant MUST BE an object which remains in scope because the same object MUST BE used during a subsequent lookup. For example,
WORKS (the same object):
self.refCon = {'a': 1} XPLMDisplay.XPLMRegisterDrawCallback(..., self.refCon) ... XPLMDisplay.XPLMUnregisterDrawCallback(..., self.refCon)
DOES NOT WORK (equivalent, but not the same object):
XPLMDisplay.XPLMRegisterDrawCallback(..., {'a': 1}) ... XPLMDisplay.XPLMUnregisterDrawCallback(..., {'a': 1})
If no subsequent lookup is required, then there is no requirement to have the object stay in scope.
Warning
If the object needs to be in scope and it’s not, the sim will crash, and in the most ugly and un-helpful way. 1
RefCon REQUIRES SAME OBJECT:
XPLMDisplay: XPLMRegisterDrawCallback + XPLMUnregisterDrawCallback
XPLMDisplay: XPLMRegisterKeySniffer + XPLMUnregisterKeySniffer
XPLMProcessing: XPLMRegisterFlightLoopCallback + XPLMUnregisterFlightLoopCallback
XPLMUtilities: XPLMRegisterCommandHandler + XPLMUnregisterCommandHandler
RefCon CAN BE ANYTHING:
XPLMDataAccess: XPLMRegisterDataAccessor
XPLMDisplay: XPLMRegisterHotKey
XPLMDisplay: XPLMCreateWindowEX (mousewheel, mouseclick, rightclick, cursor functions)
XPLMDisplay: XPLMSetWindowRefCon
XPLMMap: XPLMRegisterMapCreationHook
XPLMPlanes: XPLMPlanesAvailable
XPLMPlanes: XPLMAcquirePlanes
XPLMScenery: XPLMLoadObjectAsync
Footnotes
- 1
My consulting rates for these bugs is $500/hour.
