javatypesstackstatic-typing

Pushing/popping in a loop without dynamic typing


---Third and hopefully final EDIT--- Firstly let me say that this is a question regarding code condensing and has almost nothing to do with stacks. In the following code you will notice every block is separated by openGl pushmarix() and popmatrix()

THIS is the problem! In this method there are simply too many push/pop calls and I want to condense this so that push and pop are called only once each.

    glPushMatrix();     //<---------  push matrix
    Vec2 torPos = ...;
    glTranslatef(...);
    glRotated(...);
    glRectf(...);
    glPopMatrix();      //<---------  pop matrix

    glPushMatrix();     //<---------  push matrix
    Vec2 armPos = i.arm.getPosition().mul(30);
    glTranslatef(...);
    glRotated(...);
    glRectf(...);
    glPopMatrix()       //<---------  pop matrix

    glPushMatrix();     //<---------  push matrix
    GL11.glColor3f(...);
    Vec2 anchor = new Vec2(0,0);
    i.torsoArmJoint.getAnchorA(anchor);
    glTranslatef(....);
    glRectf(...);
    glPopMatrix();      //<---------- pop matrix

The most sensible way (it seems) to do this is by implementing a for loop. This is where the question comes in... because frankly it doesn't matter if there is some other way to solve the problem in the preceding code.

What I want to know is... how, in java, can you have a loop such as a push/pop context where you MUST have line1, followed by -whatever- then followed by line2 where the order MUST be line1, code, line2.

It seems sensible to transform the previous code into this:

    glPushMatrix();     //<---------  push matrix
    method1();
    glPopMatrix();      //<---------  pop matrix

    glPushMatrix();     //<---------  push matrix
    method2();
    glPopMatrix()       //<---------  pop matrix

    glPushMatrix();     //<---------  push matrix
    method3();
    glPopMatrix();      //<---------- pop matrix

or even this:

object1.pushmatrix();    //<---------  push matrix
object1.method();
object1.popmatrix();     //<---------  push matrix

object2.pushmatrix();    //<---------  push matrix
object2.method();
object2.popmatrix();     //<---------  push matrix

object3.pushmatrix();    //<---------  push matrix
object3.method();
object3.popmatrix();     //<---------  push matrix

But as you can see, there is a pattern here (hence the comments) which is that I have to continually call these push/pop methods for each procedure. In python, I could simply append all of the method calls into a list and then iterate through the list with a for loop like this:

methodList = [method1, method2, method3]
for method in methodList:
    glPushMatrix()     //<---------  push matrix
    method()
    glPopMatrix()      //<---------- pop matrix

Now if you don't know python just understand that there is a list of calls, then you invoke the calls iin the for loop as 'method'. As you can see, this would solve the problem because now there is only one push and one pop. However I have no idea how to do this in java.


Solution

  • My approach will be to group all of the method inside a dummy class and use reflection to access it. Below is the example of the implementation:

    public class StackExample {
    
      // Other declaration here ----------
    
      public static void main(String[] args){
    
        MethodCollection collection = new MethodCollection();
    
        String[] methods = {"method1", "method2", "method3"};
    
        // requires to catch exception just in case the method does not exist
        try {
            for (String a : methods) {
                glPushMatrix(); // <----- Push matrix
                MethodCollection.class.getMethod(a, null).invoke(collection,null);
                glPopMatrix();  // <----- Pop matrix
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
    
      }
    
     static class MethodCollection {
    
        /**
         * Empty constructor
         */
        public MethodCollection(){}
    
        public void method1(){
            System.out.println("Method 1");
        }
    
        public void method2(){
            System.out.println("Method 2");
        }
    
        public void method3(){
            System.out.println("Method 3");
        }
      }
    }