how expand a huge class in other script?

Hi


class A:
	def __init__(self, own):
		self.x=0
		self.state = 1
		#(...)
	def Update(self):
		if self.state == 2 :
			updateClass(B) #<<<<<<<<<?????????
			
			
	def method1(self):
		pass
	def method2(self):
		pass
	def method3(self):
		pass
	def method4(self):
		pass




class B:
	def Update(self):
		if self.state == 3 :
			updateClass(C) #<<<<<<<<<?????????

def main(cont):
    own=cont.owner
    if not "init" in own:
        own["init"] = 1
        own["class"]=A(own)

own["class"].Update()
			

supposing that i have one class
that become extremely long and full of dependences.
how make to “refresh” the class ?
i mean , how make to KEEP init (without resetting self.x)
and change only Update() ? using a “newUpdate” that is in another script
(and maybe keep the other method?)

I have found a way, but i’m curious to see other way(or if is the same)

i read something about “super()” but not work

Maybe an implementation of the observer pattern using call?
Just a guess though.

what there of wrong on this ?


import bge


def Update1(self):
    self.val += 0.1
    if self.val > 10.0 :
        self.Update = Update2
        
def Update2(self):
    self.val -= 0.1
    if self.val < 0.0 :
        self.Update = Update1


class Base:
    def __init__(self,own):
        self.owner = own
        self.val = 0.0
        
    def Main(self):
        self.Debug()
        self.Update()
        
    def Update(self):
        self.Update = Update1
        
    def Debug(self):
        self.owner["prop"] = self.val
        
        
        
def main(cont):
    own = cont.owner
    
    if not "init" in own:
        own["init"] = 1
        own["class"] = Base(own)
        
        
    own["class"].Main()

I expect that Update() is refresh in to Update1 and then in Update2.
so , self.val should run to 0>>10>>0>>10
but a error occour -> “self is missing”

Class functions are bound to the instance when the class is instantiated. When you replace the old function with a new one, it is not bound (check for the self attribute of the function (there will be no attribute in the non-instantiated function)
You want to “monkeypatch”. I would recommend against it; see the first post on this thread http://stackoverflow.com/questions/394770/override-a-method-at-instance-level
but, for the sake of knowledge, the second post will help you to achieve your goal

Well, I do not necessarily want to override the method.
I asked this because I thought it was the orthodox way.

if it gives problems, no.

What do you think,of my method ? this is a correct way?
or it can cause problems?


import bge


########################
def Update1(self):
    self.val += 0.1
    if self.val > 10.0 :
        self.state = 2
        
def Update2(self):
    self.val -= 0.1
    if self.val < 0.0 :
        self.state = 1
########################








class Base:
    def __init__(self,own):
        self.owner = own
        self.val = 0.0
        self.state = 1
        
        self.stateDict = {  1: Update1, 
                            2: Update2}
        
    def Main(self):
        self.Debug()
        self.Update()
        
    def Update(self):
        #self.Update = Update1
        self.stateDict[self.state](self)
        
    def Debug(self):
        self.owner["prop"] = self.val
        
        
        
def main(cont):
    own = cont.owner
    
    if not "init" in own:
        own["init"] = 1
        own["class"] = Base(own)
        
        
    own["class"].Main()

It’s not orthodox; I can’t even see what you’re trying to do. Are you attempting to do class inheritance?

class inheritance

i guess agoose77 got the point.
Sometimes i get the same Problem, classes are getting too big, and then not easy to overview… one can always use inheritance:
Example:

 
import bge

# (probably running) pseudo code, not testet

class BaseProperties():
    def __init__(self, own):
        self.owner = own
        self.val = 0.0
        self.state = 1

        self.stateDict = {  1: Update1,
                            2: Update2}
class BaseFuncions():
    def __init__(self):
        pass

    def Update1(self):
        self.val += 0.1
        if self.val > 10.0 :
            self.state = 2

    def Update2(self):
        self.val -= 0.1
        if self.val < 0.0 :
            self.state = 1




class Base(BaseProperties,BaseFunctions):
    def __init__(self,own):
        # you will probably need to instanciate inherited classes...
        BaseFunctions.__init__(self)
        BaseProperties.__init__(self, own)

    def Main(self):
        self.Debug()
        self.Update()

    def Update(self):
        #self.Update = Update1
        self.stateDict[self.state](self)

    def Debug(self):
        self.owner["prop"] = self.val



def main(cont):
    own = cont.owner

    if not "init" in own:
        own["init"] = 1
        own["class"] = Base(own)


    own["class"].Main()

I’m afraid that I don’t understand what you’re asking. Could you post in your native language as well? A lot of idioms and other expressions are lost in translation.

Here is an example of a state machine which is what you seem to be looking for


class StateMachine:
    def __init__(self):
        self.states = {}
        self.transitions = {}
        self.current_state = ""
        
    def add_state(self, state_id, state_action=None):
        self.states[state_id] = state_action
    
    def add_transition(self, state_from, state_to, condition, action=None):
        self.transitions[state_from] = [state_to, condition, action]
    
    def update(self):
        current_state = self.current_state
                
        # Test for transitions    
        if current_state in self.transitions:
            target, condition, action = self.transitions[current_state]
            if contition.__call__():
                self.current_state = target
                current_state = target
                action.__call__()
        
        # Update state actions
        if current_state in self.states:
            state_action = self.states[current_state]
            if callable(state_action):
                state_action.__call__()

yes agoose77 , it is -PROBABLY- , what I ask .(at least as alternative)
anyway i have some trouble to get how it work . (>function.call()< is necessary? or is the same as >function()< ?? )

someone can make a -simple- example switching between 2 or 3 states?

(something also with a simple float )

Thanks (PS: should be readable this post…:wink: )

You can use call() or just parenthesis, but I prefer call as it is more explicit.

Example:



class BasicMachine(StateMachine):
    def __init__(self):
        super().__init__()
        
        self.add_state("walk", self.walk)
        self.add_state("static", self.static)
        self.add_state("run", self.run)
        
        self.position = type(FakeVector, (), dict(x=0.0,y=0.0,z=0.0)) 
        self.velocity = type(FakeVector, (), dict(x=1.0,y=1.0,z=1.0)) 
        
    def set_state(self, state):
        self.current_state = state
        
    def walk(self):
        self.velocity.y = 0.1
        
    def run(self):
        self.velocity.y = 0.2
        
    def static(self):
        self.velocity.z =  0.05
        
    def move(self):
        self.position.y += self.velocity.y
        self.position.x += self.velocity.x
        self.position.z += self.velocity.z
        
        self.velocity.x = 0.0
        self.velocity.y = 0.0
        self.velocity.z = 0.0


class TestMachine(StateMachine):
    def __init__(self):
        super().__init__()
        
        self.add_state("walk", self.walk)
        self.add_state("static", self.static)
        self.add_state("run", self.run)
        
        self.add_transition(walk, static, self.is_static)
        self.add_transition(walk, run, self.is_running)
        self.add_transition(static, run, self.is_running)
        self.add_transition(static, walk, self.is_walking)
        self.add_transition(run, walk, self.is_walking)
        self.add_transition(run, static, self.is_static)
        
        self.position = type(FakeVector, (), dict(x=0.0,y=0.0,z=0.0)) 
        self.velocity = type(FakeVector, (), dict(x=1.0,y=1.0,z=1.0)) 
        
        self._state = None
        
    def set_state(self, state):
        self._state = state
        
    def is_static(self):
        return self._state == "Static"
    
    def is_running(self):
        return self._state == "Running"
    
    def is_walking(self):
        return self._state == "Walking"
    
    def walk(self):
        self.velocity.y = 0.1
        
    def run(self):
        self.velocity.y = 0.2
        
    def static(self):
        self.velocity.z =  0.05
        
    def move(self):
        self.position.y += self.velocity.y
        self.position.x += self.velocity.x
        self.position.z += self.velocity.z
        
        self.velocity.x = 0.0
        self.velocity.y = 0.0
        self.velocity.z = 0.0

The second example is basically the first example. You don’t need to do the tests because you can just set the state yourself, but the point is that you can use custom conditions for transitions.