mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-19 21:16:30 +02:00
WIP task system with lazy evaluation
This commit is contained in:
parent
f4dd4fa866
commit
89bdfd9c98
@ -35,6 +35,7 @@ dependencies {
|
||||
implementation("com.squareup.okio:okio:3.0.0")
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
implementation("com.squareup.okhttp3:okhttp:4.9.3")
|
||||
implementation("com.michael-bull.kotlin-result:kotlin-result:1.1.14")
|
||||
}
|
||||
|
||||
application {
|
||||
|
@ -88,6 +88,8 @@ class PackwizPath(path: String, base: Base) {
|
||||
* @throws RequestException
|
||||
*/
|
||||
fun source(path: String, clientHolder: ClientHolder): BufferedSource
|
||||
|
||||
operator fun div(path: String) = PackwizPath(path, this)
|
||||
}
|
||||
|
||||
interface SinkableBase: Base {
|
||||
|
@ -0,0 +1,3 @@
|
||||
package link.infra.packwiz.installer.task
|
||||
|
||||
data class CacheKey<T>(val key: String, val version: Int)
|
@ -0,0 +1,22 @@
|
||||
package link.infra.packwiz.installer.task
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class CacheManager {
|
||||
class CacheValue<T> {
|
||||
operator fun getValue(thisVal: Any?, property: KProperty<*>): T {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
operator fun setValue(thisVal: Any?, property: KProperty<*>, value: T) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
operator fun <T> get(cacheKey: CacheKey<T>): CacheValue<T> {
|
||||
return CacheValue()
|
||||
}
|
||||
|
||||
|
||||
}
|
20
src/main/kotlin/link/infra/packwiz/installer/task/Task.kt
Normal file
20
src/main/kotlin/link/infra/packwiz/installer/task/Task.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package link.infra.packwiz.installer.task
|
||||
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
|
||||
// TODO: task processing on 1 background thread; actual resolving of values calls out to a thread group
|
||||
// TODO: progress bar is updated from each of these tasks
|
||||
// TODO: have everything be lazy so there's no need to determine task ordering upfront? a bit like rust async - task results must be queried to occur
|
||||
|
||||
abstract class Task<T>(protected val ctx: TaskContext): TaskInput<T> {
|
||||
// TODO: lazy wrapper for fallible results
|
||||
// TODO: multithreaded fanout subclass/helper
|
||||
|
||||
protected fun <T> wasUpdated(value: KMutableProperty0<T>, newValue: T): Boolean {
|
||||
if (value.get() == newValue) {
|
||||
return false
|
||||
}
|
||||
value.set(newValue)
|
||||
return true
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package link.infra.packwiz.installer.task
|
||||
|
||||
/**
|
||||
* An object for storing results where result and upToDate are calculated simultaneously
|
||||
*/
|
||||
data class TaskCombinedResult<T>(val result: T, val upToDate: Boolean)
|
@ -0,0 +1,12 @@
|
||||
package link.infra.packwiz.installer.task
|
||||
|
||||
import link.infra.packwiz.installer.target.ClientHolder
|
||||
|
||||
class TaskContext {
|
||||
// TODO: thread pools, protocol roots
|
||||
// TODO: cache management
|
||||
|
||||
val cache = CacheManager()
|
||||
|
||||
val clients = ClientHolder()
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package link.infra.packwiz.installer.task
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
interface TaskInput<T> {
|
||||
/**
|
||||
* The value of this task input. May be lazily evaluated; must be threadsafe.
|
||||
*/
|
||||
val value: T
|
||||
|
||||
/**
|
||||
* True if the effective value of this input has changed since the task was last run.
|
||||
* Doesn't require evaluation of the input value; should use cached data if possible.
|
||||
* May be lazily evaluated; must be threadsafe.
|
||||
*/
|
||||
val upToDate: Boolean
|
||||
|
||||
operator fun getValue(thisVal: Any?, property: KProperty<*>): T = value
|
||||
|
||||
companion object {
|
||||
fun <T> raw(value: T): TaskInput<T> {
|
||||
return object: TaskInput<T> {
|
||||
override val value = value
|
||||
override val upToDate: Boolean
|
||||
get() = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package link.infra.packwiz.installer.task.formats.packwizv1
|
||||
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash
|
||||
import link.infra.packwiz.installer.target.path.PackwizPath
|
||||
|
||||
data class PackwizV1PackFile(val name: String, val indexPath: PackwizPath, val indexHash: Hash)
|
@ -0,0 +1,47 @@
|
||||
package link.infra.packwiz.installer.task.formats.packwizv1
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.moandjiezana.toml.Toml
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash
|
||||
import link.infra.packwiz.installer.metadata.hash.HashUtils
|
||||
import link.infra.packwiz.installer.target.path.PackwizPath
|
||||
import link.infra.packwiz.installer.task.CacheKey
|
||||
import link.infra.packwiz.installer.task.Task
|
||||
import link.infra.packwiz.installer.task.TaskCombinedResult
|
||||
import link.infra.packwiz.installer.task.TaskContext
|
||||
|
||||
class PackwizV1PackTomlTask(ctx: TaskContext, val path: PackwizPath): Task<PackwizV1PackFile>(ctx) {
|
||||
// TODO: make hierarchically defined by caller? - then changing the pack format type doesn't leave junk in the cache
|
||||
private var cache by ctx.cache[CacheKey<Hash>("packwiz.v1.packtoml.hash", 1)]
|
||||
|
||||
private class PackFile {
|
||||
var name: String? = null
|
||||
var index: IndexFileLoc? = null
|
||||
|
||||
class IndexFileLoc {
|
||||
var file: String? = null
|
||||
@SerializedName("hash-format")
|
||||
var hashFormat: String? = null
|
||||
var hash: String? = null
|
||||
}
|
||||
|
||||
var versions: Map<String, String>? = null
|
||||
}
|
||||
|
||||
private val internalResult by lazy {
|
||||
// TODO: query, parse JSON
|
||||
val packFile = Toml().read(path.source(ctx.clients).inputStream()).to(PackFile::class.java)
|
||||
|
||||
val resolved = PackwizV1PackFile(packFile.name ?: throw RuntimeException("Name required"), // TODO: better exception handling
|
||||
path.resolve(packFile.index?.file ?: throw RuntimeException("File required")),
|
||||
HashUtils.getHash(packFile.index?.hashFormat ?: throw RuntimeException("Hash format required"),
|
||||
packFile.index?.hash ?: throw RuntimeException("Hash required"))
|
||||
)
|
||||
val hash = HashUtils.getHash("sha256", "whatever was just read")
|
||||
|
||||
TaskCombinedResult(resolved, wasUpdated(::cache, hash))
|
||||
}
|
||||
|
||||
override val value by internalResult::result
|
||||
override val upToDate by internalResult::upToDate
|
||||
}
|
@ -9,6 +9,7 @@ packwiz-installer itself is under the MIT license ([Source](https://github.com/p
|
||||
- Jetbrains Annotations 13.0: Apache 2.0 ([Source](https://github.com/JetBrains/java-annotations))
|
||||
- Kotlin Standard Library 1.6.10: Apache 2.0 ([Source](https://github.com/JetBrains/kotlin))
|
||||
- toml4j 0.7.2: MIT ([Source](https://github.com/mwanji/toml4j))
|
||||
<!-- TODO: document kotlin-result -->
|
||||
|
||||
## Associated notices
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user