Problem updating list on click

Hi,

I would like to update a list of node objects (rendered as ellipses) every time the mouse is clicked.

The problem is that when mouseClicked is invoked , the grow() method appends an infinite amount of new nodes to the list instead of just one. To me it looks like there is some recursive process being triggered that I can’t really explain.

To sum up, what I would like:

  • mouse clicked --> last active node should append one new node to the list

what (I think) happens instead:

  • mouse clicked --> last active node appends a new node, that appends a new node, that appends a new node…

I’m sure the solution is right in front of me but today is one of those days when I need a little help.

def setup():
    size(400, 400)
    global collection

    collection = [Node(PVector(200, 200))]


def draw():
    None
    

def mouseClicked():
    drawNodes()
    
    
def drawNodes():
    background(255)
    for n in collection:
        n.grow()
        n.render()
        
    print len(collection)

class Node(object):
    def __init__(self, pos):
        self.pos = pos
        self.isActive = True
        
    def grow(self):
        if self.isActive:
            new_pos = PVector.fromAngle(random(TWO_PI)).setMag(10).add(self.pos)
            new_node = Node(new_pos)        #create new node at new position
            collection.append(new_node)     #append new node to collection -> PROBLEM!!!! (run for ever instead of appending once)
            self.isActive = False           #deactivate node
    
    def render(self):
        ellipse(self.pos.x, self.pos.y, 9, 9)

Ok, I think I’m breaking the rule “never update a list that is being iterated”. Creating a temporary list instead seems to work but is not very elegant. If someone has a better workaround, I’m all ears.

def setup():
    size(400, 400)
    global collection

    collection = [Node(PVector(200, 200))]


def draw():
    None
    

def mouseClicked():
    drawNodes()
    
    
def drawNodes():
    background(255)
    global temp
    temp = []
    for n in collection:
        n.grow()
        n.render()
    collection.extend(temp) #update collection with temporary array
    print len(collection)

class Node(object):
    def __init__(self, pos):
        self.pos = pos
        self.isActive = True
        
    def grow(self):
        if self.isActive:
            new_pos = PVector.fromAngle(random(TWO_PI)).setMag(10).add(self.pos)
            new_node = Node(new_pos)        #create new node at new position
            temp.append(new_node)           #append new node to temporary array 
            self.isActive = False           #deactivate node
    
    def render(self):
        ellipse(self.pos.x, self.pos.y, 9, 9)
3 Likes