Camaro Posted January 28, 2020 Share Posted January 28, 2020 (edited) Here's a little class to help execute a self-contained loop under a certain condition Spoiler import org.osbot.rs07.Bot; import org.osbot.rs07.event.Event; import java.util.function.BooleanSupplier; import java.util.function.IntSupplier; public final class Loop extends Event { private final IntSupplier task; private final BooleanSupplier condition; private final int maxLoops; private int loopCounter = 0; /** * Public method to execute the loop * * @param bot the bot instance * @param task the task to continuously perform. * Must return a number, representing the sleep time between loops * @param condition the condition signaling loop success and completion * @param maxLoops the maximum number of loops before declaring failure * @return true if the loop ended successfully */ public static boolean until(Bot bot, IntSupplier task, BooleanSupplier condition, int maxLoops) { Event loop = new Loop(task, condition, maxLoops); bot.getEventExecutor().execute(loop); return loop.hasFinished(); } // Similar method to the above but with a default maxLoops public static boolean until(Bot bot, IntSupplier task, BooleanSupplier condition) { return until(bot, task, condition, 100); } // Similar method to the above but with sleep time given as a parameter public static boolean until(Bot bot, Runnable task, BooleanSupplier condition, int sleepTime, int maxLoops) { IntSupplier taskWithReturn = () -> { task.run(); return sleepTime; }; return until(bot, taskWithReturn, condition, maxLoops); } // Similar method to the above but with default sleep time and max loops public static boolean until(Bot bot, Runnable task, BooleanSupplier condition) { return until(bot, task, condition, 600, 100); } private Loop(IntSupplier task, BooleanSupplier condition, int maxLoops) { this.task = task; this.condition = condition; this.maxLoops = maxLoops; } @Override public int execute() { if (loopCounter++ > maxLoops) // Too many loops, something went wrong, exit setFailed(); else if (condition.getAsBoolean()) // Condition successfully met, exit setFinished(); else return task.getAsInt(); return 0; } } Usage Spoiler // Drop all items in inventory Loop.until(getBot(), () -> getInventory().interact("Drop", Objects::nonNull), inventory::isEmpty); Edited February 1, 2020 by camaro 09 Quote Link to comment Share on other sites More sharing options...
dreameo Posted February 1, 2020 Share Posted February 1, 2020 Gj. I would perhaps replace IntSupplier with Runnable and just accept the additional sleep parameter. Quote Link to comment Share on other sites More sharing options...
Camaro Posted February 1, 2020 Author Share Posted February 1, 2020 1 hour ago, dreameo said: Gj. I would perhaps replace IntSupplier with Runnable and just accept the additional sleep parameter. Added something similar Quote Link to comment Share on other sites More sharing options...
Gunman Posted February 1, 2020 Share Posted February 1, 2020 This sounds and looks a lot like ConditionalLoop. Regardless nice release Quote Link to comment Share on other sites More sharing options...
Camaro Posted February 2, 2020 Author Share Posted February 2, 2020 1 hour ago, Gunman said: This sounds and looks a lot like ConditionalLoop. Regardless nice release Yeah, I could have extended ConditionalLoop instead of event, but it wouldn't be different internally because ConditionalLoop executes an event anyway. Either way, enables lambda expressions similar to the custom sleep methods that are around. Quote Link to comment Share on other sites More sharing options...