jdf / Processing.py-Bugs

A home for all bugs and feature requests about Python Mode for the Processing Development Environment.
41 stars 8 forks source link

Problem in Processing.py with Java protected variables #248

Closed jproy closed 5 years ago

jproy commented 5 years ago

I am using the audio Beads library which contains a Function.java file with an abstract class Function having a protected attribute x. I want to program in Python a subclass of Function but can't access the protected x attribute. I know I can open an access with introspection tools like Function.getDeclaredField('x') as it was suggested in a newsgroup, but it seems this is a bug in Jython, as protected methods are visible in subclasses but not protected variables. Is there any chance to eliminate this rather important "bug" as newcomers are not supposed to use introspection Java classes in Python code! Thanks for them.

jdf commented 5 years ago

Is the x in question both a method name and a field name? If so, there's no way to work around it, and the author of Beads would have to redesign that aspect of their API.

jproy commented 5 years ago

I think x is only a field name. -jpr

Envoyé de mon iPad

Le 30 oct. 2018 à 14:30, Jonathan Feinberg notifications@github.com a écrit :

Is the x in question both a method name and a field name? If so, there's no way to work around it, and the author of Beads would have to redesign that aspect of their API.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

jdf commented 5 years ago

Without a minimal, complete example, i can only continue to guess.

jproy commented 5 years ago

I will send one within a week when i have access to my computer, thanks !

Envoyé de mon iPad

Le 31 oct. 2018 à 15:07, Jonathan Feinberg notifications@github.com a écrit :

Without a minimal, complete example, i can only continue to guess.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

jproy commented 5 years ago

The Beads audio library for Java has been ported to Processing.py http://www.beadsproject.net/downloads/Beads_Processing.zip and contains a Function.java file with a protected attribute x (an array). Some Java code from Evan Merz book "Sonifying Processing" http://www.computermusicblog.com/SonifyingProcessing/Sonifying_Processing_The_Beads_Tutorial.pdf on page 101 builds an anonymous subclass of Function which redefines the calculate method, which uses the x attribute (protected so accessible to a subclass). Writing the same code in Processing.py (that is Jython) does not work as x is seen "private" (protected methods seem ok in Jython but not protected attributes, is that a bug ? If yes, this is a serious bug as many codes are too difficult in Processing.py for not specialists of introspection)... It is not the problem of an anonymous subclass, writing a full subclass is ok in Python, it's the protected x (which could be made "public" as a cool patch in Beads). Thanks, this is rather important if we want to use Beads easily in Python. Thanks for Processing.py !

jproy commented 5 years ago

Here is a link to Function.java class in Beads library. Look at the "protected x". https://github.com/orsjb/beads/blob/master/src/beads_main/net/beadsproject/beads/ugens/Function.java

jproy commented 5 years ago

Here is the code which does not work in Processing.py, x does not exist.

class Freq_Control(Function) :
      def __init__(self, *args, **kwargs) : 
            Function.__init__(self,*args, **kwargs)
     def calculate() :
           return x[0] * 100 + 600         # ERROR  x does not exist (it exists in Java)

and here is the (too complex for beginners) code to get it working, thanks to GoToLoop.

class Freq_Control(Function) :
      def __init__(self, *args, **kwargs) :
          Function.__init__(self,*args, **kwargs)
          fieldX = Function.getDeclaredField('x')
          fieldX.accessible = True 
          self.x = fieldX.get(self)

      def calculate() :
          return x[0] * 100 + 600          # OK for Jython !
jdf commented 5 years ago

I'll be pushing a build shortly. I can run the following program:

add_library('beads')

class MyFunc(Function):
    def __init__(self, mod):
        super(MyFunc, self).__init__( mod)

    def calculate(self):
        return 200 + self.x[0]*50

def setup():
    size(400, 300)
    global ac, modulator, carrier, g
    ac = AudioContext()
    modulator = WavePlayer(ac, 40, Buffer.SINE)
    carrier = WavePlayer(ac, MyFunc(modulator), Buffer.SINE)
    g = Gain(ac, 1, 0.5)
    g.addInput(carrier)
    ac.out.addInput(g)
    ac.start()

def stop():
    ac.stop()
jdf commented 5 years ago

Fixed in build 3045, available now.

jproy commented 5 years ago

Thanks a lot Jonathan ! Did you patch the embedded Jython, or at Processing level ?

jproy commented 5 years ago

In (Mac) Processing 3.4, the last mode is 3042 with "Add a mode..." ?

jdf commented 5 years ago

You can see the change in the linked-to commit, https://github.com/jdf/processing.py/commit/e3eec7b2692ddebdf30a8b9f1390953a3920baa0

Just uninstall and re-install the mode; they don't keep the mode versions up to date on the Processing server.