/** * A collection of helper functions for common utility tasks. */ object HelperFunctions { /** * Computes the total number of steps needed to process the given total volume. * * This takes the total volume that needs to be processed and th * and calculates the total steps required. * Usage examples: * ``` * val total = 550 * val perStep = 200 * val steps = calculateTotalSteps(total, perStep) // 3 steps * * val steps = calculateTotalSteps(1000, 100) // 10 steps * ``` * * @param totalVolume the total amount that needs to be processed * @param volumePerStep the amount to process per step * @return the number of steps required to process the total volume */ fun calculateTotalSteps(totalVolume: Int, volumePerStep: Int) = totalVolume / volumePerStep + if (totalVolume % volumePerStep > 0) { 1 } else { 0 } /** * Prints a progress report to console showing current step, total steps, elapsed time, and estimated remaining time. * * This takes the current step number, total steps, and elapsed duration and prints a progress report. * Typical usage is to call this within a loop, passing the loop index for current step and total loop count. * * * Usage example: * ``` * val totalSteps = 100 * val start = System.currentTimeMillis() * for (i in 1..totalSteps) { * // Do work * * report(i, totalSteps, System.currentTimeMillis() - start) * } * ``` * * @param step The current step number * @param of The total number of steps * @param dur The elapsed duration so far in milliseconds */ fun report(step: Int, of: Int, dur: Long) { val remaining = (dur / step) * (of - step) print("\rStep $step of $of (${prettyTimeString(dur)} complete\t|\t~${prettyTimeString(remaining)} remaining) ") } /** * Converts a duration in milliseconds to a human-readable string. * * This takes a duration in ms and converts it to a formatted string like "2h13m4s". * * Usage example: * * ``` * val duration = 72134 // ms * val timeStr = prettyTimeString(duration) * // "1m12s" * ``` * * @param durationMillis The duration to convert, in milliseconds * @return A string representation of the duration, in the format XhYmZs */ fun prettyTimeString(durationMillis: Long): String { if (durationMillis == 0L) { return "No time data yet" } val millisPerSecond = 1000L val millisPerMinute = 60L * millisPerSecond val millisPerHour = 60L * millisPerMinute return if (durationMillis > millisPerHour) { return "${durationMillis / millisPerHour}h${(durationMillis % millisPerHour) / millisPerMinute}m${(durationMillis % millisPerMinute) / millisPerSecond}s" } else if (durationMillis > millisPerMinute) { return "${(durationMillis % millisPerHour) / millisPerMinute}m${(durationMillis % millisPerMinute) / millisPerSecond}s" } else { "${(durationMillis % millisPerMinute) / millisPerSecond}s" } } /** * Gets the current mouse pointer location and returns it as a val declaration string. * * This method uses the [getPointerLocationAfter] method to get the current * mouse pointer location after a small delay. * * It then formats this location into a string declaring a val with the provided * variable name, like: * * ``` * val location = getPointerLocationAsValDeclarationString("clickPoint") * // val clickPoint = Point(123, 456) * ``` * * The delay before getting the pointer location helps ensure the mouse has * settled after any prior movements. * * @param varName The name to use for the variable in the declaration string. * @return A string declaring a val with the pointer location. */ fun getPointerLocationAsValDeclarationString(orchestrator: Orchestrator, varName: String): String { val info = orchestrator.getPointerLocationAfterDelay(5) return "val $varName = Point(${info.x}, ${info.y})" } }