All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.engine.MethodStep Maven / Gradle / Ivy

Go to download

MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.

The newest version!
/*
  Copyright 2006 by Sean Luke and George Mason University
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/

package sim.engine;
import java.lang.reflect.*;
import sim.util.*;

/** 
    A Steppable which calls an underlying method using Java's reflection system.  The underlying method can either have no arguments
    or have one argumen (SimState), and is specified by its name as a String.

    

You can use MethodStep to call methods on classes that aren't Steppables. For example, if you have an object myObject and wish to submit both its foo and bar methods (no arguments) to be called at various times when the Schedule sees fit, you might do this:


    MyClass myObject = ... ;
    schedule.scheduleRepeating( ... , new MethodStep(myObject, "foo"), ...);
    schedule.scheduleRepeating( ... , new MethodStep(myObject, "bar"), ...);
    

This will call the foo() method and bar() method to be called at the appropriate times on myObject.

You can also use MethodStep to pop up objects which aren't Steppables by their nature. For example:


    JFrame myJFrame = ... ;
    schedule.schedule( ... , new MethodStep(myJFrame, "show"), ...);
    

MethodStep can also be called on methods which expect to be passed in the Steppable's SimState argument. When the MethodStep is called, it passes its argument to them. You do this by adding a true to the constructor:


    MyClass myObject = ... ;
    schedule.scheduleRepeating( ... , new MethodStep(myObject, "baz", true), ...);
    schedule.scheduleRepeating( ... , new MethodStep(myObject, "quux", true), ...);
    

This will call the baz(SimState) method and quux(SimState) method to be called at the appropriate times on myObject.

This method is mostly to help in ease of porting: but it's not good Java. Reflection is slow and violates all sorts of design contracts -- generally speaking, you should use anonymous Steppables intead. For example, the examples above could have instead been written this way:


    final MyClass myObject = ... ;
    final JFrame myJFrame = ... ;
    schedule.scheduleRepeating( ... , new Steppable() { public void step(SimState state) { myObject.foo() } }, ...);
    schedule.scheduleRepeating( ... , new Steppable() { public void step(SimState state) { myObject.foo() } }, ...);
    schedule.schedule( ... , new Steppable() { public void step(SimState state) { myJFrame.show() } }, ...);
    schedule.scheduleRepeating( ... , new Steppable() { public void step(SimState state) { myObject.baz(state) } }, ...);
    schedule.scheduleRepeating( ... , new Steppable() { public void step(SimState state) { myObject.quux(state) } }, ...);
    
*/ public class MethodStep implements Steppable { private static final long serialVersionUID = 1; Method method; Object object; boolean passInSimState; public MethodStep(Object object, String methodName) { this(object,methodName,false); } public MethodStep(Object object, String methodName, boolean passInSimState) { this.object = object; this.passInSimState = passInSimState; if (object==null) { throw new NullPointerException("MethodStep asked to call the method " + methodName + (passInSimState ? "\"(SimState state)" : "\"") + " on a null object"); } try { if (passInSimState) this.method = object.getClass().getMethod(methodName, new Class[]{SimState.class}); else this.method = object.getClass().getMethod(methodName, new Class[]{}); } catch (NoSuchMethodException ex) // make runtime exception { throw new RuntimeException("Could not find a public method called \"" + methodName + (passInSimState ? "\"(SimState state)" : "\"") + " in the class " + object.getClass()); } catch (SecurityException ex) { throw new RuntimeException("Could not find a public method called \"" + methodName + (passInSimState ? "\"(SimState state)" : "\"") + " in the class " + object.getClass()); } } public void step(final SimState state) { try { if (passInSimState) method.invoke(object, new Object[] { state }); else method.invoke(object, (Object[]) null); } catch (IllegalAccessException ex) // make runtime exception { // generally should not happen -- the getMethod() method should only return public methods throw new RuntimeException("Could not find a public method called \"" + method + (passInSimState ? "\"(SimState state)" : "\"") + " in the class " + object.getClass()); } catch (IllegalArgumentException ex) { throw new RuntimeException("Could not find a public method called \"" + method + (passInSimState ? "\"(SimState state)" : "\"") + " in the class " + object.getClass()); } catch (InvocationTargetException ex) { /** At the moment, Java 1.3 cannot do causes, so we don't include this for compatability reasons. Maybe we'll uncomment it later. */ /* Throwable t = new RuntimeException("On calling \"" + methodName +"\" in the class " + object.getClass() + ", an Exception was raised in the called method."); t.initCause(ex.getCause()); throw t; */ throw new RuntimeException("On calling \"" + method + (passInSimState ? "\"(SimState state)" : "\"") + " in the class " + object.getClass() + ", an Exception was raised in the called method.", ex); } catch (NullPointerException ex) { // should not be able to occur -- we've already verified that object is not null. throw new NullPointerException("MethodStep asked to call the method " + method + (passInSimState ? "\"(SimState state)" : "\"") + " on a null object"); } // dont' catch (ExceptionInInitializerError ex) -- let it throw through like any error } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy