Browse Source
High Priority Fixes: - Fix thread pool management: Add shared preprocessingExecutor to prevent creating new thread pools per detection - Add proper thread pool shutdown with grace period in cleanup() method - Remove memory leak from repeated Executors.newFixedThreadPool() calls Code Quality Infrastructure: - Add MatUtils.kt with safe Mat resource management extension functions - Add MLResult.kt with standardized error handling for ML operations - Prepare foundation for systematic error handling improvements Performance Impact: - Eliminates thread pool creation overhead during inference - Reduces memory pressure from abandoned thread pools - Maintains all original ML detection functionality 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>arch-002-ml-inference-engine
3 changed files with 163 additions and 9 deletions
@ -0,0 +1,83 @@ |
|||
package com.quillstudios.pokegoalshelper.ml |
|||
|
|||
/** |
|||
* Result wrapper for ML operations to standardize error handling |
|||
*/ |
|||
sealed class MLResult<out T> |
|||
{ |
|||
data class Success<T>(val data: T) : MLResult<T>() |
|||
data class Error(val exception: Throwable, val message: String) : MLResult<Nothing>() |
|||
|
|||
/** |
|||
* Returns the data if successful, or null if error |
|||
*/ |
|||
fun getOrNull(): T? = when (this) |
|||
{ |
|||
is Success -> data |
|||
is Error -> null |
|||
} |
|||
|
|||
/** |
|||
* Returns the data if successful, or the default value if error |
|||
*/ |
|||
fun getOrDefault(default: T): T = when (this) |
|||
{ |
|||
is Success -> data |
|||
is Error -> default |
|||
} |
|||
|
|||
/** |
|||
* Execute block if successful |
|||
*/ |
|||
inline fun onSuccess(block: (T) -> Unit): MLResult<T> |
|||
{ |
|||
if (this is Success) block(data) |
|||
return this |
|||
} |
|||
|
|||
/** |
|||
* Execute block if error |
|||
*/ |
|||
inline fun onError(block: (Throwable, String) -> Unit): MLResult<T> |
|||
{ |
|||
if (this is Error) block(exception, message) |
|||
return this |
|||
} |
|||
|
|||
/** |
|||
* Transform the data if successful |
|||
*/ |
|||
inline fun <R> map(transform: (T) -> R): MLResult<R> = when (this) |
|||
{ |
|||
is Success -> try { Success(transform(data)) } |
|||
catch (e: Exception) { Error(e, "Transform failed: ${e.message}") } |
|||
is Error -> this |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Helper functions for creating results |
|||
*/ |
|||
inline fun <T> mlTry(operation: () -> T): MLResult<T> |
|||
{ |
|||
return try |
|||
{ |
|||
MLResult.Success(operation()) |
|||
} |
|||
catch (e: Exception) |
|||
{ |
|||
MLResult.Error(e, "Operation failed: ${e.message}") |
|||
} |
|||
} |
|||
|
|||
inline fun <T> mlTryWithMessage(message: String, operation: () -> T): MLResult<T> |
|||
{ |
|||
return try |
|||
{ |
|||
MLResult.Success(operation()) |
|||
} |
|||
catch (e: Exception) |
|||
{ |
|||
MLResult.Error(e, "$message: ${e.message}") |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
package com.quillstudios.pokegoalshelper.ml |
|||
|
|||
import org.opencv.core.Mat |
|||
|
|||
/** |
|||
* Utility functions for safe Mat resource management |
|||
*/ |
|||
|
|||
/** |
|||
* Execute a block with automatic Mat cleanup |
|||
*/ |
|||
inline fun <T> Mat.use(block: (Mat) -> T): T |
|||
{ |
|||
return try |
|||
{ |
|||
block(this) |
|||
} |
|||
finally |
|||
{ |
|||
this.release() |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Execute a block with multiple Mats and automatic cleanup |
|||
*/ |
|||
inline fun <T> useMats(vararg mats: Mat, block: () -> T): T |
|||
{ |
|||
return try |
|||
{ |
|||
block() |
|||
} |
|||
finally |
|||
{ |
|||
mats.forEach { it.release() } |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Create a new Mat and execute block with automatic cleanup |
|||
*/ |
|||
inline fun <T> withNewMat(block: (Mat) -> T): T |
|||
{ |
|||
return Mat().use(block) |
|||
} |
|||
|
|||
/** |
|||
* Create multiple new Mats and execute block with automatic cleanup |
|||
*/ |
|||
inline fun <T> withNewMats(count: Int, block: (List<Mat>) -> T): T |
|||
{ |
|||
val mats = (1..count).map { Mat() } |
|||
return try |
|||
{ |
|||
block(mats) |
|||
} |
|||
finally |
|||
{ |
|||
mats.forEach { it.release() } |
|||
} |
|||
} |
|||
Loading…
Reference in new issue