gpt4 book ai didi

scala - 如果输入文件不变,如何使自定义任务避免重做工作?

转载 作者:行者123 更新时间:2023-12-04 12:23:14 25 4
gpt4 key购买 nike

我有一个游戏的多项目设置。有一个非常具体的子项目叫做“资源”,它只包含要打包到 jar 中的图像、声音和 texfiles 等文件。

我有一个处理图像并打包它们的自定义任务。在“src/main”中,我使用了一个文件夹“预处理”,图像应该放在那里,一个“非托管”文件夹用来存放其他所有东西。通过运行我的任务,“预处理”中的所有图像都被打包并输出到“资源”,“非托管”中的所有内容都按原样复制。

val texturePacker = TaskKey[Unit]("texture-packer", "Runs libgdx's Texture Packer")

val texturePackerTask = texturePacker := {
println("Packaging textures...")
val inputDir = file("resources/src/main/preprocess")
val outputDir = file("resources/src/main/resources")

val folders = inputDir.asFile.listFiles filter (_.isDirectory)

println("Sub-Folders:" + folders.mkString(", "))

// Run Texture Packer
for (subfolder <- folders) {
println("Building assets for:" + subfolder)
val args = Array(subfolder.toString, outputDir.toString, subfolder.getName)
com.badlogic.gdx.tools.imagepacker.TexturePacker2.main(args)
}

// Copy unmanaged resources
IO.copyDirectory(file("resources/src/main/unmanaged"), file("resources/src/main/resources"))
}

然后在设置中的“资源”项目:
...
packageBin in Compile <<= packageBin in Compile dependsOn(texturePacker)
...

其他子项目依赖于与其运行关联的 packageBin。这样,每当我运行项目时,我都会获得最新的资源状态。我不希望它随需应变。问题是每次运行都需要很长时间来处理。我知道 SBT 支持缓存 SBT FAQ但我不明白如何让它适应我的任务。

如果未修改文件夹列表中子文件夹中的文件,如何使我的自定义任务避免重做工作?

最佳答案

解决方案

这是一个可能适合您的解决方案。但是,我并不完全理解 FileFunction.cached有效(代码后面的更多信息),所以这可能不是最好的解决方案:

val testCache = TaskKey[Unit]("test-cache", "Test SBT's cache")

val testCacheTask = testCache := {
println("Testing cache ...")

val inputDir = file("test/src") /* Take direct subdirectories from here */
val outputDir = file("test/dest") /* Create archives here */
val cacheDir = file("test/cache") /* Store cache information here */

/* Get all direct subdirectories of inputDir */
val folders = inputDir.asFile.listFiles.filter{_.isDirectory}

folders.foreach{folder =>
/* Get all files in the folder (not recursively) */
val files = folder.listFiles.toSet

/* Wrap actual function in a function that provides basic caching
* functionalities.
*/
val cachedFun =
FileFunction.cached(cacheDir / folder.name,
FilesInfo.lastModified, /* inStyle */
FilesInfo.exists) /* outStyle */
{(inFiles: Set[File]) =>

createJarFromFolder(folder,
inFiles,
outputDir / (folder.name + ".jar"))
}

/* Call wrapped function with files in the current folder */
cachedFun(files)
}
}

/* Creates a JAR archive with all files (this time recursively) in
* the given folder.
*/
val createJarFromFolder = (folder: File, inFiles: Set[File], outJar: File) => {
println("At least one of the %d files in %s have changed. Creating %s."
.format(inFiles.size, folder, outJar))

/* Replace this by your actual operation */
val cmdSeq = Seq("jar", "cf", outJar.toString, "-C" , folder + "/", ".")
println("cmdSeq = " + cmdSeq)
println("jar: " + cmdSeq.!!)

Set(outJar)
}

笔记
  • 我对cached的理解就是,它检查 inFiles用于修改,并且如果 调用实际操作一 集中的文件已更改。 Changed 的​​确切含义由 inStyle 决定。论据 cached .
  • 直接将目录传递给 cached 会很好,以便在该目录中的任何内容发生更改时执行实际操作。但是,我怀疑目前是否可行。
  • 我不太明白实际操作返回的文件集的行为是什么(此处: Set(outJar) )。我假设 outStyle论据 cached与此有关,我预计 createJarFromFolder在 JAR 不存在时调用(无论输入文件如何更改),但情况似乎并非如此。也就是说,如果您删除了一个 JAR 文件,但没有更改相应目录中的文件之一,则不会重新创建该 JAR。
  • 该代码有点狡猾,因为在决定该文件夹中是否发生更改时,它只考虑位于特定文件夹顶部的文件。你可能想让那个递归。

  • 结语

    我很想看到一种更好的方式来使用 SBT 的缓存功能。如果您从邮件列表中获得更多信息,请在此处发布。

    关于scala - 如果输入文件不变,如何使自定义任务避免重做工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11640715/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com