Multiple inheritence: combining VerletParticle() with WB_Point()

Hi all,

I’m working on a sketch where a Cell class needs to inherit both from ToxiclibsVerletParticle() and Hemesh WB_Point(). Ideally I would like the Cell object to share specific attributes from the two libraries (WB_Point connected by VerletSprings).

Is that possible in Python mode ?

With other Processing libraries I used to write something like this:

class Cell(VerletParticle2D, Locatable):
    def __init__(self, x, y):
        super(Cell, self).__init__(x, y)
        self.isActive = False
        
    def getLocation(self):
        return PVector(self.x(), self.y())

but this time, class Cell(VerletParticle2D, WB_Point) returns the following error:

processing.app.SketchException: TypeError: Error when calling the metaclass bases no multiple inheritance for Java classes: toxi.physics2d.VerletParticle2D and wblut.geom.WB_Point
at jycessing.mode.run.SketchRunner.convertPythonSketchError(SketchRunner.java:242)
at jycessing.mode.run.SketchRunner.lambda$2(SketchRunner.java:119)
at java.lang.Thread.run(Thread.java:748)

Is there a way to get around this error ?

1 Like

Which library does Locatable come from? Surely it’s an interface, not a Java class, right?

Java can implement multiple interfaces; but can only extend 1 class!

Jython, just like Python, can inherit from multiple Python classes, creating a mixin among them.

However, when it’s a Java class, Jython can only inherit 1!

Given you can pick 1 only, as a poor workaround, you can make the other Java class become a property of the picked 1:

class Cell(VerletParticle2D):
    def __init__(c, *args):
        super(Cell, c).__init__(*args)
        c.wb_p = WB_Point(*args)
        c.isActive = False

In the subclass above, VerletParticle2D was chosen as the parent Java class, while WB_Point became 1 of its new properties as wb_p.

I’m not sure, but I believe you might want properties x & y to be the same for both VerletParticle2D & WB_Point, right?

Anyways, I’ve made methods makeVerletEqualPoint() & makePointEqualVerlet() as another poor workaround:

add_library('toxiclibs')
add_library('hemesh')

def setup():
    print VerletParticle2D, WB_Point, ENTER

    global cell
    cell = Cell(random(10), random(10))
    print cell, ENTER, cell.wb_p, ENTER

    print cell.wb_p.scaleSelf(random(5))
    print cell.makeVerletEqualPoint(), ENTER

    print cell.scaleSelf(random(5))
    print cell.makePointEqualVerlet()

    exit()


class Cell(VerletParticle2D):
    def __init__(c, *args, **kws):
        super(Cell, c).__init__(*args, **kws)
        c.wb_p = WB_Point()
        c.makePointEqualVerlet()
        c.isActive = False


    def makeVerletEqualPoint(c):
        return c.set(c.wb_p.x, c.wb_p.y)


    def makePointEqualVerlet(c):
        c.wb_p.set(c.x(), c.y())
        return c.wb_p
3 Likes

Thank you for the reply and detailed explanations (as always!).

Locatable comes from the GiCentre library and is indeed an interface, my bad.

I ended-up with the same workaround you’re suggesting and it works “ok” so far. I guess I’ll stick with this solution for now.

Thanks again

The other option is composition. Have your new class simply contain an instance each of the two class objects, and your container class will map their interfaces out as needed / keep them in sync.

1 Like