@@ -10,6 +10,33 @@ import kotlinx.coroutines.TimeoutCancellationException
1010import kotlinx.coroutines.delay
1111import kotlinx.coroutines.withTimeout
1212
13+ /* *
14+ * A [Task] represents a time-critical activity that executes a suspending action function.
15+ * It is designed to automate in-game activities without the need for strict event-based programming,
16+ * thanks to the use of suspending functions which allow for linear coding.
17+ *
18+ * A [Task] can have event listeners, but they are only active while the action function is running.
19+ *
20+ * It supports a builder pattern, allowing you to chain configuration methods like [withDelay],
21+ * [withTimeout], [withMaxAttempts], [withRepeats], [onSuccess], [onRetry], [onTimeout], [onFailure], and [onRepeat]
22+ * to construct a [Task] instance.
23+ * This makes it easy to build complex flows of nested tasks.
24+ *
25+ * CAUTION: When implementing the `onAction` function,
26+ * ensure that the function adheres to thread safety measures.
27+ * This includes avoiding write operations on non-synchronized in-game data
28+ * unless explicitly running on the game thread using `runSafeOnGameThread { ... }`.
29+ *
30+ * @property delay The delay before the task starts, in milliseconds.
31+ * @property timeout The maximum time that the task is allowed to run, in milliseconds.
32+ * @property maxAttempts The maximum number of attempts to execute the task before it is considered failed.
33+ * @property repeats The number of times the task should be repeated.
34+ * @property onSuccess The action to be performed when the task completes successfully.
35+ * @property onRetry The action to be performed when the task is retried after a failure or timeout.
36+ * @property onTimeout The action to be performed when the task times out.
37+ * @property onRepeat The action to be performed each time the task is repeated.
38+ * @property onException The action to be performed when the task encounters an exception.
39+ */
1340abstract class Task <Result >(
1441 private var delay : Long = 0L ,
1542 private var timeout : Long = Long .MAX_VALUE ,
@@ -21,18 +48,43 @@ abstract class Task<Result>(
2148 private var onRepeat : (suspend Task <Result >.(Int ) -> Unit ) = {},
2249 private var onException : (suspend Task <Result >.(Throwable ) -> Unit ) = {},
2350) {
51+ private val creationTimestamp = System .currentTimeMillis()
52+ private val age: Long get() = System .currentTimeMillis() - creationTimestamp
53+ open val name: String get() = this ::class .simpleName ? : " Task"
54+
2455 val syncListeners = Subscriber ()
2556 private val concurrentListeners = Subscriber ()
2657
2758 /* *
28- * Make sure to only do read operations on the game thread!
29- * Use `runSafeOnGameThread { ... }` to execute safe write operations on the game thread.
30- * @return The [Result] of the action
59+ * Executes the main action of the task.
60+ *
61+ * This function should only perform read operations on the game thread due to potential concurrency issues.
62+ * If write operations are necessary, they should be wrapped in the `runSafeOnGameThread { ... }` function to ensure thread safety.
63+ *
64+ * @return The result of the action, of type [Result].
3165 */
3266 abstract suspend fun SafeContext.onAction (): Result
3367
68+ /* *
69+ * This function is called when the task is cancelled.
70+ * It should be overridden for tasks that need to perform cleanup operations,
71+ * such as cancelling a block breaking progress, releasing resources,
72+ * or stopping any ongoing operations that were started by the task.
73+ */
3474 open fun SafeContext.onCancel () {}
3575
76+ /* *
77+ * Executes the task with the configured parameters.
78+ *
79+ * This function will attempt to execute the task for a specified number of attempts and repeats.
80+ * It handles delays before task execution, task timeouts, and task cancellations.
81+ * It also manages the lifecycle of event listeners associated with the task.
82+ *
83+ * @return The result of the task execution, represented as a [TaskResult].
84+ * This could be a successful result ([TaskResult.Success]), a cancellation ([TaskResult.Cancelled]),
85+ * a failure ([TaskResult.Failure]) due to an exception, or a timeout
86+ * ([TaskResult.Timeout]).
87+ */
3688 suspend fun execute (): TaskResult <Result > {
3789 var attempt = 1
3890 var iteration = 0
@@ -107,50 +159,100 @@ abstract class Task<Result>(
107159 }
108160 }
109161
110- private val creationTimestamp = System .currentTimeMillis()
111- val age: Long get() = System .currentTimeMillis() - creationTimestamp
112- val name: String get() = this ::class .simpleName ? : " Task"
113-
162+ /* *
163+ * Sets the delay before the task starts.
164+ *
165+ * @param delay The delay in milliseconds.
166+ * @return This task instance with the updated delay.
167+ */
114168 fun withDelay (delay : Long ): Task <Result > {
115169 this .delay = delay
116170 return this
117171 }
118172
173+ /* *
174+ * Sets the timeout for a single attempt of the task
175+ *
176+ * @param timeout The timeout in milliseconds
177+ * @return This task instance with the updated timeout.
178+ */
119179 fun withTimeout (timeout : Long ): Task <Result > {
120180 this .timeout = timeout
121181 return this
122182 }
123183
184+ /* *
185+ * Sets the maximum number of attempts to execute the task before it is considered failed.
186+ *
187+ * @param maxAttempts The maximum number of attempts.
188+ * @return This task instance with the updated maximum attempts.
189+ */
124190 fun withMaxAttempts (maxAttempts : Int ): Task <Result > {
125191 this .maxAttempts = maxAttempts
126192 return this
127193 }
128194
195+ /* *
196+ * Sets the number of times the task should be repeated.
197+ *
198+ * @param repeats The number of repeats.
199+ * @return This task instance with the updated number of repeats.
200+ */
129201 fun withRepeats (repeats : Int ): Task <Result > {
130202 this .repeats = repeats
131203 return this
132204 }
133205
206+ /* *
207+ * Sets the action to be performed when the task completes successfully.
208+ *
209+ * @param action The action to be performed.
210+ * @return The task instance with the updated success action.
211+ */
134212 fun onSuccess (action : suspend (Result ) -> Unit ): Task <Result > {
135213 this .onSuccess = action
136214 return this
137215 }
138216
217+ /* *
218+ * Sets the action to be performed when the task is retried after a failure or timeout.
219+ *
220+ * @param action The action to be performed.
221+ * @return The task instance with the updated retry action.
222+ */
139223 fun onRetry (action : suspend Task <Result >.() -> Unit ): Task <Result > {
140224 this .onRetry = action
141225 return this
142226 }
143227
228+ /* *
229+ * Sets the action to be performed when the task times out.
230+ *
231+ * @param action The action to be performed.
232+ * @return The task instance with the updated timeout action.
233+ */
144234 fun onTimeout (action : suspend Task <Result >.() -> Unit ): Task <Result > {
145235 this .onTimeout = action
146236 return this
147237 }
148238
239+ /* *
240+ * Sets the action to be performed when the task encounters an exception.
241+ *
242+ * @param action The action to be performed.
243+ * @return The task instance with the updated exception action.
244+ */
149245 fun onFailure (action : suspend Task <Result >.(Throwable ) -> Unit ): Task <Result > {
150246 this .onException = action
151247 return this
152248 }
153249
250+ /* *
251+ * Sets the action to be performed each time the task is repeated.
252+ *
253+ * @param action The action to be performed.
254+ * @return The task instance with the updated repeat action.
255+ */
154256 fun onRepeat (action : suspend Task <Result >.(Int ) -> Unit ): Task <Result > {
155257 this .onRepeat = action
156258 return this
0 commit comments