The Topology Plugin

In the digital art scene of the 90s and early 00s it's fair to say that there was one dominant programming paradigm embodied, chiefly, by Max/MSP and it's predecessors and progeny. This woeful homogeny is of course today very much under attack (first SuperCollider, then Processing and the various "live coding" avant gardes). Field itself continues the assault. Still it's the case that people can't resist recreating over and over again essentially the same, data-flow-based tools as went before (Apple alone have 3 by our count Quartz Composer, Shake and there's one in Color as well).

We've always found the classic criticisms of such environments (especially when stacked against more 'traditional' text based programming) to be fairly fatal — for example, neither iteration nor recursion are well represented in most of them, which seems odd, because most of them are deployed in domains with algorithms that are best expressed in these terms (many reverbs for example in sound, and many filtering operations, for example, in video).

But clearly, there's something about drawing lines between boxes in order to create code that people get into.

Not to be outdone — and to feed our voracious appetite for paradigms tired or new — Field comes with a "Topology Plugin" that allows you, yes, to draw connections between visual elements. Unlike everybody else's implementation this plugin leaves it completely up to you and your code as to what you actually do with these connections. Left by themselves they don't do anything (but paint themselves).

First of all you'll need to make sure that the TopologyPlugin is enabled in the plugin manager.

Making a connection

To make a connection use the topology mouse tool:

You can select the tool from the bottom left, or you can just press and hold "T". This allows you to drag from A to B:

Either way, you'll get an connection.

That's a connection from A to B.

Some notes on connections

Some things that you should know about connections:

  • Connections are just a different kind of Visual Element or "Box" — that is, they are a non-box shaped "box". You can select them just like you can select other lines, you can delete them by right selecting and then right clicking on them. You can stick code in them. You can stick data in them (they have _self variables). You can even draw connections between them and other things.

  • Connections are meaningless to Field_. We can think of a few uses for data-bearing connections, and maybe even code bearing connections. In any case, all these things come naturally with the architecture of Field, and you might find yourself provoked into thinking of some completely novel uses of these things.

  • Left alone connections don't do anything — don't expect anything about the rest of what's on your canvas to notice. We'll see below that code can talk about connections (so these things are not purely decorative) but their use is not specified inside Field.

Using these connections

So far we've been able to decorate our canvases with connections. What to do with them?

We're still not going to answer what (that's up to your imagination), but we will tell you how. The topology plugin supplies a new property to every element that allows you to get at the topology you've just created. In the most simple case

_self.topology_.up()

Returns a list of elements that are connected to this element. In the case of B in our example so far this returns A. In A, this code will return the empty list. To get [B] call _self.topology_.down().

That's really all there is to it. Using what these two functions return gives you all kinds of access into these other boxes — you can pass data to them (by setting _self.topology_.up()[0].something = 10 you are setting a variable something in the scope of another box. You could call functions defined inside these boxes otherBox.someFunction_(myData). Perhaps even more interestingly you can "start and stop" other boxes — otherBox.begin().

Control Flow

Just for the sake of motivating this whole plugin — although we're sure you'll find your own uses for these perennial box connections — let's take a closer look at this last point.

It's actually quite fascinating. Now we have a new, strictly additional, way of creating "control flow" inside Field's code. We know about the for loop and the while loop and the if statement, now we can draw a diagram and have code "pass" control to another box completely.

To really see this in action let's first make a little loop:

Now, in each box we'd like some code like this:

def doSomething():
    for n in range(0,100):
        print "%s running @ %s " % (_self, n)
        yield 1
    _self.end()
    _self.topology_.up()[0].begin()

_r = doSomething()

This code is going print "Element xxx running @ 0" all the way up to 99 and then stop, just as it passes control over to the "next" element. (If the use of yield or what _r is doing makes no sense to you then we suggest that you take a look at VisualElementLifecycles and GeneratorExamples right now).

We could copy and paste this code into each box. But that might get tedious (if we then have to change each box). Instead we make a new element that will act as a template for all of our little graph, type the above code into that and then modify the delegation heirarchy so that our graph elements look to the template to get their properties (include their code).

Hopefully, you ought to be able to piece this together using the documentation at SelfAndProperties. But a short review — to do this you code use a mouse tool:

and take a look at this Selection "axis" to make sure that everything is in order:

Now we can run, say, box A and watch it start, run for 100 cycles, start "B", have it run for 100 cycles and so on.

You can change the logic on a per element basis, you could also try a more complex branching graph and have something like:

def ongoing():
    for n in range(0,100):
        yield 1
    _self.end()
    
    next = _self.topology_.up()
    if (len(next)==0):
        pass
    else:
        next[int(Math.random()*len(next))].begin()

_r = ongoing()

This randomly picks from possible connections. We've also had parts of pieces that have used these techniques and kept statistics inside the nodes concerning when last they were 'visited' by the execution. Now you are in a spot where you can control and modify the tendencies towards breadth of exploration or closeness of repetition of some structure (rendering style, musical rhythm etc.). Now that's a parameter worth keyframing. Here's a still from part of the graph for OpenEnded Group's piece Forest:

In installation, this graph is traversed simultaneously by 5 execution flows. It's extremely difficult to see how art would survive programming this in pure text.

So you should consider the TopologyPlugin, like so many other things in Field, as an abstract building block. You're not using a feature of our Field, you are building a feature of your Field.