Skip to content

Commit 93a9a87

Browse files
committed
task soft-failing and on-fail callbacks
1 parent bd9357e commit 93a9a87

File tree

6 files changed

+102
-58
lines changed

6 files changed

+102
-58
lines changed

src/main/kotlin/com/lambda/command/commands/TaskCommand.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ object TaskCommand : LambdaCommand(
4242
execute {
4343
this@TaskCommand.info("Clearing all tasks")
4444
RootTask.cancel()
45-
RootTask.clear()
4645
}
4746
}
4847
}

src/main/kotlin/com/lambda/config/AutomationConfig.kt

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,63 +33,63 @@ import com.lambda.util.NamedEnum
3333

3434

3535
open class AutomationConfig(
36-
override val name: String,
37-
configuration: Configuration = AutomationConfigs
36+
override val name: String,
37+
configuration: Configuration = AutomationConfigs
3838
) : Configurable(configuration), Automated {
39-
enum class Group(override val displayName: String) : NamedEnum {
40-
Build("Build"),
41-
Break("Break"),
42-
Interact("Interact"),
43-
Rotation("Rotation"),
44-
Inventory("Inventory"),
45-
Hotbar("Hotbar"),
46-
Eat("Eat"),
47-
Render("Render"),
48-
Debug("Debug")
49-
}
39+
enum class Group(override val displayName: String) : NamedEnum {
40+
Build("Build"),
41+
Break("Break"),
42+
Interact("Interact"),
43+
Rotation("Rotation"),
44+
Inventory("Inventory"),
45+
Hotbar("Hotbar"),
46+
Eat("Eat"),
47+
Render("Render"),
48+
Debug("Debug")
49+
}
5050

51-
override val buildConfig = BuildSettings(this, Group.Build)
52-
override val breakConfig = BreakSettings(this, Group.Break)
53-
override val interactConfig = InteractSettings(this, Group.Interact)
54-
override val rotationConfig = RotationSettings(this, Group.Rotation)
55-
override val inventoryConfig = InventorySettings(this, Group.Inventory)
56-
override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
57-
override val eatConfig = EatSettings(this, Group.Eat)
51+
override val buildConfig = BuildSettings(this, Group.Build)
52+
override val breakConfig = BreakSettings(this, Group.Break)
53+
override val interactConfig = InteractSettings(this, Group.Interact)
54+
override val rotationConfig = RotationSettings(this, Group.Rotation)
55+
override val inventoryConfig = InventorySettings(this, Group.Inventory)
56+
override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
57+
override val eatConfig = EatSettings(this, Group.Eat)
5858

59-
companion object {
59+
companion object {
6060
context(module: Module)
61-
fun MutableAutomationConfig.setDefaultAutomationConfig(
62-
name: String = module.name,
63-
edits: (AutomationConfig.() -> Unit)? = null
61+
fun MutableAutomationConfig.setDefaultAutomationConfig(
62+
name: String = module.name,
63+
edits: (AutomationConfig.() -> Unit)? = null
6464
) {
6565
this.defaultAutomationConfig = AutomationConfig("$name Automation Config").apply { edits?.invoke(this) }
6666
}
6767

68-
fun MutableAutomationConfig.setDefaultAutomationConfig(
69-
name: String,
70-
edits: (AutomationConfig.() -> Unit)? = null
68+
fun MutableAutomationConfig.setDefaultAutomationConfig(
69+
name: String,
70+
edits: (AutomationConfig.() -> Unit)? = null
7171
) {
7272
defaultAutomationConfig = AutomationConfig("$name Automation Config").apply { edits?.invoke(this) }
7373
}
7474

75-
object DEFAULT : AutomationConfig("Default") {
76-
val renders by setting("Render", false).group(Group.Render)
77-
val avoidDesync by setting("Avoid Desync", true, "Cancels incoming inventory update packets if they match previous actions").group(Group.Debug)
78-
val desyncTimeout by setting("Desync Timeout", 30, 1..30, 1, unit = " ticks", description = "Time to store previous inventory actions before dropping the cache") { avoidDesync }.group(Group.Debug)
79-
val showAllEntries by setting("Show All Entries", false, "Show all entries in the task tree").group(Group.Debug)
80-
val shrinkFactor by setting("Shrink Factor", 0.001, 0.0..1.0, 0.001).group(Group.Debug)
81-
val ignoreItemDropWarnings by setting("Ignore Drop Warnings", false, "Hides the item drop warnings from the break manager").group(Group.Debug)
75+
object DEFAULT : AutomationConfig("Default") {
76+
val renders by setting("Render", false).group(Group.Render)
77+
val avoidDesync by setting("Avoid Desync", true, "Cancels incoming inventory update packets if they match previous actions").group(Group.Debug)
78+
val desyncTimeout by setting("Desync Timeout", 30, 1..30, 1, unit = " ticks", description = "Time to store previous inventory actions before dropping the cache") { avoidDesync }.group(Group.Debug)
79+
val showAllEntries by setting("Show All Entries", false, "Show all entries in the task tree").group(Group.Debug)
80+
val shrinkFactor by setting("Shrink Factor", 0.001, 0.0..1.0, 0.001).group(Group.Debug)
81+
val ignoreItemDropWarnings by setting("Ignore Drop Warnings", false, "Hides the item drop warnings from the break manager").group(Group.Debug)
8282
val managerDebugLogs by setting("Manager Debug Logs", false, "Prints debug logs from managers into chat").group(Group.Debug)
8383

84-
@Volatile
85-
var drawables = listOf<Drawable>()
84+
@Volatile
85+
var drawables = listOf<Drawable>()
8686

87-
init {
88-
onStaticRender { esp ->
87+
init {
88+
onStaticRender { esp ->
8989
if (renders)
9090
drawables.forEach { it.render(esp) }
91-
}
92-
}
93-
}
94-
}
91+
}
92+
}
93+
}
94+
}
9595
}

src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ sealed class BreakResult : BuildResult() {
101101
override fun resolve() {
102102
selectStack {
103103
isItem(badItem).not()
104-
}.transferByTask(HotbarContainer)?.execute(task)
104+
}.transferByTask(HotbarContainer)?.softFail()?.execute(task)
105105
}
106106

107107
override fun compareResult(other: ComparableResult<Rank>) =

src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ sealed class GenericResult : BuildResult() {
9999

100100
context(task: Task<*>, _: AutomatedSafeContext)
101101
override fun resolve() {
102-
neededSelection.transferByTask(HotbarContainer)?.execute(task)
102+
neededSelection.transferByTask(HotbarContainer)?.softFail()?.execute(task)
103103
}
104104

105105
override fun render(esp: TransientRegionESP) {

src/main/kotlin/com/lambda/module/modules/player/Printer.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ object Printer : Module(
3838
description = "Automatically prints schematics",
3939
tag = ModuleTag.PLAYER
4040
) {
41-
private fun isLitematicaAvailable(): Boolean = runCatching {
42-
Class.forName("fi.dy.masa.litematica.Litematica")
43-
true
44-
}.getOrDefault(false)
45-
4641
private val range by setting("Range", 5, 1..7, 1)
4742
private val air by setting("Air", false)
4843

@@ -58,7 +53,7 @@ object Printer : Module(
5853
}
5954

6055
onEnable {
61-
if (!isLitematicaAvailable()) {
56+
if (!litematicaAvailable()) {
6257
logError("Litematica is not installed!")
6358
disable()
6459
return@onEnable
@@ -76,4 +71,9 @@ object Printer : Module(
7671

7772
onDisable { buildTask?.cancel(); buildTask = null }
7873
}
74+
75+
private fun litematicaAvailable(): Boolean = runCatching {
76+
Class.forName("fi.dy.masa.litematica.Litematica")
77+
true
78+
}.getOrDefault(false)
7979
}

src/main/kotlin/com/lambda/task/Task.kt

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ typealias TaskGeneratorUnit<R> = SafeContext.(R) -> Unit
3838

3939
abstract class Task<Result> : Nameable, Muteable {
4040
var parent: Task<*>? = null
41+
var parentPausing = false
4142
val subTasks = mutableListOf<Task<*>>()
4243
var state = State.Init
4344
override val isMuted: Boolean get() = state == State.Paused || state == State.Init
@@ -50,6 +51,10 @@ abstract class Task<Result> : Nameable, Muteable {
5051
private var nextTaskOrNull: TaskGeneratorOrNull<Result>? = null
5152
private var onFinish: TaskGeneratorUnit<Result>? = null
5253

54+
private var onFail: TaskGenerator<Unit>? = null
55+
private var onFailOrNull: TaskGeneratorOrNull<Unit>? = null
56+
private var softFail = false
57+
5358
enum class State {
5459
Init,
5560
Running,
@@ -115,6 +120,7 @@ abstract class Task<Result> : Nameable, Muteable {
115120
parent = owner
116121
LOG.info("${owner.name} started $name")
117122
if (pauseParent) {
123+
parentPausing = true
118124
LOG.info("$name pausing parent ${owner.name}")
119125
if (owner !is RootTask) owner.pause()
120126
}
@@ -165,9 +171,13 @@ abstract class Task<Result> : Nameable, Muteable {
165171
}
166172

167173
@Ta5kBuilder
168-
fun cancel() {
174+
fun cancel() = internalCancel(true)
175+
176+
private fun internalCancel(removeFromParent: Boolean = true) {
169177
runSafe { onCancel() }
170178
cancelSubTasks()
179+
if (removeFromParent) parent?.subTasks?.remove(this)
180+
if (parentPausing) parent?.activate()
171181
if (this is RootTask) return
172182
if (state == State.Completed || state == State.Cancelled) return
173183
state = State.Cancelled
@@ -176,11 +186,7 @@ abstract class Task<Result> : Nameable, Muteable {
176186

177187
@Ta5kBuilder
178188
fun cancelSubTasks() {
179-
subTasks.forEach { it.cancel() }
180-
}
181-
182-
fun clear() {
183-
subTasks.forEach { it.clear() }
189+
subTasks.forEach { it.internalCancel(removeFromParent = false) }
184190
subTasks.clear()
185191
}
186192

@@ -192,10 +198,27 @@ abstract class Task<Result> : Nameable, Muteable {
192198
e: Throwable,
193199
stacktrace: MutableList<Task<*>> = mutableListOf(),
194200
) {
201+
if (softFail) {
202+
cancelSubTasks()
203+
parent?.subTasks?.remove(this)
204+
}
195205
state = State.Failed
196206
unsubscribe()
197207
stacktrace.add(this)
198-
parent?.failure(e, stacktrace) ?: run {
208+
runSafe {
209+
onFail?.let { taskGen ->
210+
val task = taskGen(this, Unit)
211+
onFail = null
212+
parent?.let { owner -> task.execute(owner) }
213+
} ?: onFailOrNull?.let { taskGen ->
214+
val task = taskGen(this, Unit)
215+
onFailOrNull = null
216+
parent?.let { owner -> task?.execute(owner) }
217+
}
218+
} ?: if (softFail) {
219+
if (parentPausing) parent?.activate()
220+
return
221+
} else parent?.failure(e, stacktrace) ?: run {
199222
val message = buildString {
200223
stacktrace.firstOrNull()?.let { first ->
201224
append("${first.name} failed: ${e.message}\n")
@@ -286,6 +309,28 @@ abstract class Task<Result> : Nameable, Muteable {
286309
return this
287310
}
288311

312+
@Ta5kBuilder
313+
fun onFail(taskGenerator: TaskGenerator<Unit>): Task<Result> {
314+
require(onFail == null) { "Cannot have multiple onFail callbacks on a single task" }
315+
onFail = taskGenerator
316+
softFail()
317+
return this
318+
}
319+
320+
@Ta5kBuilder
321+
fun onFailOrNull(taskGenerator: TaskGeneratorOrNull<Unit>): Task<Result> {
322+
require(onFailOrNull == null) { "Cannot have multiple onFailOrNull callbacks on a single task" }
323+
onFailOrNull = taskGenerator
324+
softFail()
325+
return this
326+
}
327+
328+
@Ta5kBuilder
329+
fun softFail(): Task<Result> {
330+
softFail = true
331+
return this
332+
}
333+
289334
/**
290335
* Registers a finalization action to be executed after the current task completes.
291336
*

0 commit comments

Comments
 (0)