Loading...
Logo
Processing Forum
Hello,

this problem is really hard to describe, cannot paste all the code which contains the problem.

I have written a class called "ControllerManager", which makes it even more convenient to use some of the CP5 Controllers, performs some auto-layout and enables Serialisation. All the controllers of a single ControllerManager are pooled in a ControllerGroup. Each ControllerGroup contains an own instance of ControlP5.

To give you an idea how it works:

Copy code
  1. cm = new ControllerManager("foo", this, controlWindow);
  2. // add a Slider which can be addressed with "SIZE", current value: 10, min: 0, max: 20
  3. cm.addInt("SIZE", 10, 0, 20);
  4. ...
  5. cm.showControllers();
  6. ...
  7. this.ellipse(x,y, cm.getInt("SIZE"), cm.getInt("SIZE"));

"this" is a reference to the PApplet.

"controlWindow" is an instance of a class called "PseudoWindow", which just gives some offset and size Infos about where the controllers should actually be displayed.

There is another class called "GraphElement", each instance containing his own ControllerManager to control some Parameters. During Runtime, it is possible to select a certain GraphElement to edit it with the Controllers managed by the ControllerManager.

The Problem is: When a controller Group of any ControllerManager is shown (= the controllers are visible and can be changed...), it will take sth. like 50 % of CPU Performance when the frameRate is 30!

EDIT: If no ControllerManager is selected (= no Controllers are visible, all Controllers have got the "hideControllers" Message), the CPU performance is fine.

I already tried a lot to isolate the problem without success:

- The problem appears even when there is only a single Instance of the ControllerManager
- I commented out the ControllListener, no effect on performance
- I commented out all the logic which enables Serialisation, no effect on performance
EDIT: if the Controllers aren't pooled in a group, no effect on performance

I found out, if i did not add any Controllers to the Manager, there is no performance problem. So, just an empty ControllerGroup is displayed.

I know it is an imposition, but has anybody of you an idea where to search to solve the problem?

I'm thinking about to rewrite the ControllerManager with G4P, but, the current implementation works perfect besides the performance problem...

Many Thanks for reading anyway!

Replies(1)

Sorry for this long listing, here's the code of ControllerManager.
I know i use some deprecated methods of CP5, (addToggle, addBang), but i'm quite sure that they don't cause the performance leak.

Don't know if you need to understand the Listener in detail, as mentioned, the problem appears when it is commented out...

I guess this is not a good + clean programming style, but well, it works.

Perhaps the whole design is off the track and the goal can be achieved much easier?
Copy code
  1. package de.xxx.processing.util.controlermanager;

    import controlP5.*;
    import java.util.HashMap;
    import processing.core.*;

    public class ControllerManager implements IFC_ControllerManager {
     
      private HashMap<String, Parameter> parameters;
      private PseudoWindow controlWindow;
     
      private ControlP5 cp5;
      private ControlGroup group;
     
      private Listener theListener;

      private int verticalControllerPosition = 10;

      public ControllerManager(String name, PApplet applet, PseudoWindow controlWindow) {
        this.controlWindow = controlWindow;
        parameters = new HashMap<String, Parameter>(10);
        this.cp5 = new ControlP5(applet);
        group = cp5.addGroup(name, controlWindow.xPos + 1, controlWindow.yPos + 12);
        group.setSize(controlWindow.width - 2, controlWindow.height - 12);
        group.setBackgroundColor(255);
        theListener = new Listener();
        showControllers();
      }

      public Bang addBang(String name) {
        Bang bang = cp5.addBang(name, 5, verticalControllerPosition, 10, 10)
          .setGroup(group)
            .setColorCaptionLabel(0);
        verticalControllerPosition += 28;
        return bang;
      }
     
      public void addBangListener(String name, ControlListener theListener) {
        cp5.getController(name).addListener(theListener);
      }

     public void addBool(String name, boolean val) {
        parameters.put(name, new Parameter<Boolean>(val));
        cp5.addToggle(name, true, 5, verticalControllerPosition, 10, 10)
          .setValue(val)
            .setGroup(group)
              .setColorCaptionLabel(0)
                .addListener(theListener);
        verticalControllerPosition += 28;
      }

      public void addInt(String name, int val, int minVal, int maxVal) {
        parameters.put(name, new Parameter<Integer>(val));
        cp5.addSlider(name, minVal, maxVal, 5, verticalControllerPosition, group.getWidth()-50, 20)
          .setValue(val)
            .setGroup(group)
              .setColorCaptionLabel(0)
                .setNumberOfTickMarks(maxVal - minVal +1)
                  .addListener(theListener);
        verticalControllerPosition += 28;
      }

      public void addFloat(String name, float val, float minVal, float maxVal) {
        parameters.put(name, new Parameter<Float>(val));
        cp5.addSlider(name, minVal, maxVal, 5, verticalControllerPosition, group.getWidth()-50, 20)
          .setValue(val)
            .setGroup(group)
              .setColorCaptionLabel(0)
                .addListener(theListener);
        verticalControllerPosition += 28;
      }

      public void addRange(String name, float minVal, float maxVal, float absMinVal, float absMaxVal) {
        parameters.put(name+"min", new Parameter<Float>(minVal));
        parameters.put(name+"max", new Parameter<Float>(maxVal));
        cp5.addRange(name, absMinVal, absMaxVal, minVal, maxVal, 5, verticalControllerPosition,      group.getWidth()-50, 20)
          .setGroup(group)
            .setColorCaptionLabel(0)
              .addListener(theListener);
        verticalControllerPosition += 28;
      }

      public boolean getBool(String name) {
        return (Boolean) parameters.get(name).getVal();
      }

      public int getInt(String name) {
        return (Integer) parameters.get(name).getVal();
      }

      public float getFloat(String name) {
        return (Float) parameters.get(name).getVal();
      }

      public void setBool(String name, boolean val) {
        parameters.get(name).setVal(val);
      }

      public void setInt(String name, int val) {
        parameters.get(name).setVal(val);
      }

      public void setFloat(String name, float val) {
        parameters.get(name).setVal(val);
      }
     
      public class Listener implements ControlListener {
        public void controlEvent(ControlEvent theEvent) {
          String name = theEvent.getController().getName();
          Parameter p = parameters.get(name);
          if (theEvent.getController() instanceof Slider) {
            Slider s = (Slider) theEvent.getController();
            if (s.getNumberOfTickMarks() > 0) {
              int val = Math.round(theEvent.getController().getValue());
              p.setVal(val);
            }
            else {
              p.setVal(theEvent.getController().getValue());
            }
          }
          else {
            if (theEvent.getController() instanceof Toggle) {
              float f = theEvent.getController().getValue();
              if (f == 0) {
                p.setVal(false);
              }
              else {
                p.setVal(true);
              }
            }
            else {
              if (theEvent.getController() instanceof Range) {
                Range range = (Range) theEvent.getController();
                Parameter min = parameters.get(name+"min");
                Parameter max = parameters.get(name+"max");
                min.setVal(range.getLowValue());
                max.setVal(range.getHighValue());
              }
            }
          }
        }
      }
     
      public void showControllers(){
        group.show();
      }
     
      public  void hideControllers(){
        group.hide();
      }
    }
the class Parameter is used to "mirror" the values of the Controller. It will be used for Serialisation.
Copy code
  1. class Parameter<T> {

      T val;

      Parameter(T val) {
        this.val = val;
      }

      T getVal() {
        return val;
      }

      void setVal(T val) {
        this.val = val;
      }
    }