Skip to main content
added 561 characters in body
Source Link
Scheintod
  • 135
  • 1
  • 7

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner): #Note: where has my argument gone?

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner ) # Note: Object is stored nowhere

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to __init__ but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?

EDIT: To make it more clearly: If I do "normal" inheritance in Python this is how it works:

class Parent:

    def __init__( self ):
        self.a = "FOO"

    def talk():
        return a
    
class Child( Parent ):

    def __init__( self, b ):
        Parent.__init__( self )
        self.b = b
    
    def talk( self ):
        return self.a + self.b


child = Child( "BAR" )
print( child.talk() )
    
someglobal[ 'child' ] = child

so the parameter "BAR" gets passed as second argument b to the constructor of class A. The constructor calls the other one from class A and I end up with an instance which I have to store somewhere globally in order to access it from somewhere else.

Compare this to blender's version: The already instantiated object is passed as an argument to the constructor. But it doesn't end up as second argument to __init__ but gets somehow mangled in while the second argument is something else (in fact it seems to be nothing. trying to access it yields in an error). The finally constructed instance is then somehow stored in the global dictionary for objects and replaces the old one.

These somehows and somethings are which I'm interested in. What's happening here?

EDIT2: Taken from the linked documentation:

def __init__(self, old_owner):

# "old_owner" can just be ignored. At this point, "self" is
# already the object in the scene, and "old_owner" has been
# destroyed.

If I only read the python code in this module (my first example) this is not what is supposed to happen python-wise. So what makes self the object and what destroys the old owner? Is this some c-code magic patched into the python interpreter? Or is this some python magic somewhere in KX_GameObject? Or something else?

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner): #Note: where has my argument gone?

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner ) # Note: Object is stored nowhere

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to __init__ but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?

EDIT: To make it more clearly: If I do "normal" inheritance in Python this is how it works:

class Parent:

    def __init__( self ):
        self.a = "FOO"

    def talk():
        return a
    
class Child( Parent ):

    def __init__( self, b ):
        Parent.__init__( self )
        self.b = b
    
    def talk( self ):
        return self.a + self.b


child = Child( "BAR" )
print( child.talk() )
    
someglobal[ 'child' ] = child

so the parameter "BAR" gets passed as second argument b to the constructor of class A. The constructor calls the other one from class A and I end up with an instance which I have to store somewhere globally in order to access it from somewhere else.

Compare this to blender's version: The already instantiated object is passed as an argument to the constructor. But it doesn't end up as second argument to __init__ but gets somehow mangled in while the second argument is something else (in fact it seems to be nothing. trying to access it yields in an error). The finally constructed instance is then somehow stored in the global dictionary for objects and replaces the old one.

These somehows and somethings are which I'm interested in. What's happening here?

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner): #Note: where has my argument gone?

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner ) # Note: Object is stored nowhere

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to __init__ but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?

EDIT: To make it more clearly: If I do "normal" inheritance in Python this is how it works:

class Parent:

    def __init__( self ):
        self.a = "FOO"

    def talk():
        return a
    
class Child( Parent ):

    def __init__( self, b ):
        Parent.__init__( self )
        self.b = b
    
    def talk( self ):
        return self.a + self.b


child = Child( "BAR" )
print( child.talk() )
    
someglobal[ 'child' ] = child

so the parameter "BAR" gets passed as second argument b to the constructor of class A. The constructor calls the other one from class A and I end up with an instance which I have to store somewhere globally in order to access it from somewhere else.

Compare this to blender's version: The already instantiated object is passed as an argument to the constructor. But it doesn't end up as second argument to __init__ but gets somehow mangled in while the second argument is something else (in fact it seems to be nothing. trying to access it yields in an error). The finally constructed instance is then somehow stored in the global dictionary for objects and replaces the old one.

These somehows and somethings are which I'm interested in. What's happening here?

EDIT2: Taken from the linked documentation:

def __init__(self, old_owner):

# "old_owner" can just be ignored. At this point, "self" is
# already the object in the scene, and "old_owner" has been
# destroyed.

If I only read the python code in this module (my first example) this is not what is supposed to happen python-wise. So what makes self the object and what destroys the old owner? Is this some c-code magic patched into the python interpreter? Or is this some python magic somewhere in KX_GameObject? Or something else?

added 1326 characters in body
Source Link
Scheintod
  • 135
  • 1
  • 7

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner): #Note: where has my argument gone?

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner ) # Note: Object is stored nowhere

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to init__init__ but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?

EDIT: To make it more clearly: If I do "normal" inheritance in Python this is how it works:

class Parent:

    def __init__( self ):
        self.a = "FOO"

    def talk():
        return a
    
class Child( Parent ):

    def __init__( self, b ):
        Parent.__init__( self )
        self.b = b
    
    def talk( self ):
        return self.a + self.b


child = Child( "BAR" )
print( child.talk() )
    
someglobal[ 'child' ] = child

so the parameter "BAR" gets passed as second argument b to the constructor of class A. The constructor calls the other one from class A and I end up with an instance which I have to store somewhere globally in order to access it from somewhere else.

Compare this to blender's version: The already instantiated object is passed as an argument to the constructor. But it doesn't end up as second argument to __init__ but gets somehow mangled in while the second argument is something else (in fact it seems to be nothing. trying to access it yields in an error). The finally constructed instance is then somehow stored in the global dictionary for objects and replaces the old one.

These somehows and somethings are which I'm interested in. What's happening here?

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner):

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner )

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to init but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner): #Note: where has my argument gone?

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner ) # Note: Object is stored nowhere

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to __init__ but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?

EDIT: To make it more clearly: If I do "normal" inheritance in Python this is how it works:

class Parent:

    def __init__( self ):
        self.a = "FOO"

    def talk():
        return a
    
class Child( Parent ):

    def __init__( self, b ):
        Parent.__init__( self )
        self.b = b
    
    def talk( self ):
        return self.a + self.b


child = Child( "BAR" )
print( child.talk() )
    
someglobal[ 'child' ] = child

so the parameter "BAR" gets passed as second argument b to the constructor of class A. The constructor calls the other one from class A and I end up with an instance which I have to store somewhere globally in order to access it from somewhere else.

Compare this to blender's version: The already instantiated object is passed as an argument to the constructor. But it doesn't end up as second argument to __init__ but gets somehow mangled in while the second argument is something else (in fact it seems to be nothing. trying to access it yields in an error). The finally constructed instance is then somehow stored in the global dictionary for objects and replaces the old one.

These somehows and somethings are which I'm interested in. What's happening here?

Source Link
Scheintod
  • 135
  • 1
  • 7

How does BGE inheritance work

Following the documentation at: https://docs.blender.org/api/blender_python_api_2_76_2/bge.types.KX_GameObject.html I can extend a game object with:

class Mine( types.KX_GameObject ):

    def __init__( self, old_owner):

         #stuff

def activate( controller ): # Called from Controller

    Mine( controller.owner )

But I'm missing what's doing the magic here. Somehow the controller not gets passed as second argument to init but as first and the game object is internally (?) exchanged (?) with mine.

So how is this working exactly? Is there some blender-foo or is this something Python can do for me which I'm not aware of?