WeakValueDictionary Tutorial


A WeakValueDictionary allows you to store objects while still allowing them to be garbage collected. For instance, lets say you want to have a dictionary containing all the enemies on the map. When those enemies are removed from play, they will no longer be in the WeakValueDictionary.


Garbage Collection


First have an object make the dictionary and send itself as a message. The game object should have a bool property 'doEnd'.

import bge
# https://docs.python.org/3/library/weakref.html#weakref.WeakValueDictionary
from weakref import WeakValueDictionary
# Place a WeakValueDictionary somewere we can get it.
bge.logic.globalDict['refIds'] = WeakValueDictionary()
refIds = bge.logic.globalDict['refIds']
own = bge.logic.getCurrentController().owner
# (A) id
refId = str( id(own) )
# This dose not create a reference to own.  Own can still be garbage collected.
refIds[refId] = own
# refId was converted to a string so we can send it through a message.
bge.logic.sendMessage('currentPlayer', refId)
# Turn this on or off to see the difference.
if own['doEnd']:  own.endObject()

Then have a second object receive the message. The game object should have a message sensor and a 'currentPlayer' property set to False.

import bge
cont = bge.logic.getCurrentController()
own = cont.owner
msgSen = cont.sensors['Message']
if msgSen.positive:
  refIds = bge.logic.globalDict['refIds']
  # Iterate throu all messages
  for i in range(msgSen.frameMessageCount):
    if msgSen.subjects[i] == 'currentPlayer':
      objId = msgSen.bodies[i]
      # If the other object has been garbage collected, then this will retuen None.
      own['currentPlayer'] = refIds.get(objId, None)
# Make sure own has this game property.


(A) id

id gives us a unique integer identifier for an object. We convert it to a string so that it can be sent through bge.logic.message. Note that the an objects id is only garented unique during the objects lifetime.


Edit this text to ask or answer questions

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License