attaching a script instance to an object

basically i have a class that i want to use on several objects, and i want the script to be initialized once for each object so i can use variables set in init for each object separately

ex a class like this:


class toBeInstanced:
    def __init__(self, cont):
        self.var = 0
        #etc other variables

    def main(self):
        #code

now to call the class i can do either this, but here the variables set in init will be reset every time the script runs:


def main():
    toBeInstanced_ = toBeinstanced(logic.getCurrentController())
    toBeInstanced_.main()

or this, but then the variables set in init are the same for all calls of the script:


toBeInstanced_ = toBeinstanced(logic.getCurrentController())

def main():
    toBeInstanced_.main()

what i would like instead that in the line
toBeInstanced_ = toBeinstanced(logic.getCurrentController())
toBeInstanced_ is a variable of the controller so i can have separate instances of the class for every object i run it from.

Use try and except to create the class. Store the reference on the object dictionary.

Sent from my Nexus 7 using Tapatalk HD

To echo agoose77’s advice, I attach the class to the object dictionary with some init-bootstrapping. This snipit assumes that you are running this as a module.


def main(cont):
  
  owner = cont.owner
  
  # Init boot-strap
  if 'object' not in owner:
    owner['object'] = toBeInstanced(cont)

  owner['object'].main()

Though I usually, don’t store the controller. Instead I pass it though the ‘main’ function as a parameter.


def main(cont):
  
  owner = cont.owner
  
  # Init boot-strap
  if 'object' not in owner:
    owner['object'] = toBeInstanced()

  owner['object'].main(cont)

excellent.
i am assuming ‘object’ is an arbitrairy string

That is correct. I think of it as “the object” so that’s what I call it. But the string-name could be anything.

You can use a function to deal with object creation

...
myInstance = getMyInstance()
...
def getMyInstance():
    try:
        return bge.logic.getCurrentController()["myInstance"]
    except AttributeError:
        myInstance = MyInstance()
        bge.logic.getCurrentController()["myInstance"] = myInstance
        return myInstance


A good alternative is to run a separate controller just for initalization.

def init():
    bge.logic.getCurrentController()["myInstance"] = MyInstance()

def doYourLogic():
    myInstance = bge.logic.getCurrentController()["myInstance"]