mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-23 03:23:17 -04:00
chore(purity): MapPathing
This commit is contained in:
parent
3af195fe11
commit
62b033d1d2
@ -49,6 +49,9 @@ allprojects {
|
||||
apply(plugin = "io.github.yairm210.purity-plugin")
|
||||
configure<yairm210.purity.PurityConfiguration>{
|
||||
wellKnownPureFunctions = setOf(
|
||||
"java.util.regex.Pattern.matcher",
|
||||
"java.util.regex.Matcher.find",
|
||||
"java.util.regex.Matcher.replaceAll",
|
||||
)
|
||||
wellKnownReadonlyFunctions = setOf(
|
||||
"com.badlogic.gdx.math.Vector2.len",
|
||||
@ -61,6 +64,9 @@ allprojects {
|
||||
"com.badlogic.gdx.files.FileHandle.isDirectory",
|
||||
"com.badlogic.gdx.files.FileHandle.isFile",
|
||||
"com.badlogic.gdx.files.FileHandle.name",
|
||||
|
||||
"kotlin.Throwable.getStackTrace",
|
||||
"java.lang.StackTraceElement.getClassName",
|
||||
)
|
||||
wellKnownPureClasses = setOf(
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.unciv.logic.map
|
||||
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import yairm210.purity.annotations.InternalState
|
||||
import java.util.PriorityQueue
|
||||
|
||||
|
||||
@ -37,6 +38,7 @@ data class TilePriority(val tile: Tile, val priority: Float)
|
||||
* val path = aStarSearch.findPath(goalTile)
|
||||
* ```
|
||||
*/
|
||||
@InternalState
|
||||
class AStar(
|
||||
val startingPoint: Tile,
|
||||
private val predicate : (Tile) -> Boolean,
|
||||
|
@ -15,6 +15,7 @@ object MapPathing {
|
||||
* Otherwise, we set every tile to have equal value since building a road on any of them makes the original movement cost irrelevant.
|
||||
*/
|
||||
@Suppress("UNUSED_PARAMETER") // While `from` is unused, this function should stay close to the signatures expected by the AStar and getPath `heuristic` parameter.
|
||||
@Readonly
|
||||
private fun roadPreferredMovementCost(unit: MapUnit, from: Tile, to: Tile): Float{
|
||||
// hasRoadConnection accounts for civs that treat jungle/forest as roads
|
||||
// Ignore road over river penalties.
|
||||
@ -24,6 +25,7 @@ object MapPathing {
|
||||
return 1f
|
||||
}
|
||||
|
||||
@Readonly
|
||||
fun isValidRoadPathTile(unit: MapUnit, tile: Tile): Boolean {
|
||||
val roadImprovement = tile.ruleset.roadImprovement
|
||||
val railRoadImprovement = tile.ruleset.railroadImprovement
|
||||
@ -49,6 +51,7 @@ object MapPathing {
|
||||
* @param endTile The destination tile of the path.
|
||||
* @return A sequence of tiles representing the path from startTile to endTile, or null if no valid path is found.
|
||||
*/
|
||||
@Readonly
|
||||
fun getRoadPath(unit: MapUnit, startTile: Tile, endTile: Tile): List<Tile>?{
|
||||
return getPath(unit,
|
||||
startTile,
|
||||
@ -73,6 +76,7 @@ object MapPathing {
|
||||
* It takes a MapUnit, a 'from' Tile, and a 'to' Tile, returning a Float value representing the heuristic cost estimate.
|
||||
* @return A list of tiles representing the path from the startTile to the endTile. Returns null if no valid path is found.
|
||||
*/
|
||||
@Readonly
|
||||
private fun getPath(unit: MapUnit,
|
||||
startTile: Tile,
|
||||
endTile: Tile,
|
||||
@ -104,7 +108,7 @@ object MapPathing {
|
||||
* Gets the connection to the end tile. This does not take into account tile movement costs.
|
||||
* Takes in a civilization instead of a specific unit.
|
||||
*/
|
||||
@Readonly @Suppress("purity") // todo continue
|
||||
@Readonly
|
||||
fun getConnection(civ: Civilization,
|
||||
startTile: Tile,
|
||||
endTile: Tile,
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.unciv.utils
|
||||
|
||||
import yairm210.purity.annotations.Immutable
|
||||
import yairm210.purity.annotations.Pure
|
||||
import yairm210.purity.annotations.Readonly
|
||||
import java.time.Instant
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@ -21,10 +24,10 @@ object Log {
|
||||
* Log tags (= class names) **containing** these Strings will not be logged.
|
||||
* You _can_ disable the default exclusions with an empty `-DnoLog=` argument.
|
||||
*/
|
||||
val disableLogsFrom = (
|
||||
@Immutable val disableLogsFrom = (
|
||||
System.getProperty("noLog")
|
||||
?: "Battle,Music,Sounds,Translations,WorkerAutomation,assignRegions,RoadBetweenCitiesAutomation"
|
||||
).split(',').filterNot { it.isEmpty() }.toMutableSet()
|
||||
).split(',').filterNot { it.isEmpty() }.toSet()
|
||||
|
||||
/**
|
||||
* Add -DonlyLog=<comma-separated-list-of-partial-class-names> to only log specific classes.
|
||||
@ -32,13 +35,15 @@ object Log {
|
||||
* [disableLogsFrom] will still be respected if this is set.
|
||||
* Note you cannot disable all logging with `-DonlyLog=`, use `-DonlyLog=~~~` instead.
|
||||
*/
|
||||
@Immutable
|
||||
val enableLogsFrom = (
|
||||
System.getProperty("onlyLog")
|
||||
?: ""
|
||||
).split(',').filterNot { it.isEmpty() }.toMutableSet()
|
||||
).split(',').filterNot { it.isEmpty() }.toSet()
|
||||
|
||||
var backend: LogBackend = DefaultLogBackend()
|
||||
|
||||
@Readonly
|
||||
fun shouldLog(tag: Tag = getTag()): Boolean {
|
||||
return !backend.isRelease() && !isTagDisabled(tag)
|
||||
}
|
||||
@ -54,6 +59,7 @@ object Log {
|
||||
*
|
||||
* The [params] can contain value-producing lambdas, which will be called and their value used as parameter for the message instead.
|
||||
*/
|
||||
@Pure @Suppress("purity") // log considered pure everywhere
|
||||
fun debug(msg: String, vararg params: Any?) {
|
||||
if (backend.isRelease()) return
|
||||
debug(getTag(), msg, *params)
|
||||
@ -159,7 +165,7 @@ interface LogBackend {
|
||||
fun error(tag: Tag, curThreadName: String, msg: String)
|
||||
|
||||
/** Do not log on release builds for performance reasons. */
|
||||
fun isRelease(): Boolean
|
||||
@Readonly fun isRelease(): Boolean
|
||||
|
||||
/** Get string information about operation system */
|
||||
fun getSystemInfo(): String
|
||||
@ -209,6 +215,7 @@ private fun doLog(logger: (Tag, String, String) -> Unit, tag: Tag, msg: String,
|
||||
logger(tag, Thread.currentThread().name, formattedMessage)
|
||||
}
|
||||
|
||||
@Pure
|
||||
private fun isTagDisabled(tag: Tag): Boolean {
|
||||
return Log.disableLogsFrom.any { it in tag.name } ||
|
||||
(Log.enableLogsFrom.isNotEmpty() && Log.enableLogsFrom.none { it in tag.name })
|
||||
@ -231,14 +238,16 @@ private fun replaceLambdasWithValues(params: Array<out Any?>): Array<out Any?> {
|
||||
}
|
||||
|
||||
|
||||
@Readonly
|
||||
private fun getTag(): Tag {
|
||||
@Suppress("ThrowingExceptionsWithoutMessageOrCause")
|
||||
val firstOutsideStacktrace = Throwable().stackTrace.filter { "com.unciv.utils.Log" !in it.className }.first()
|
||||
val firstOutsideStacktrace = Throwable().stackTrace.first { "com.unciv.utils.Log" !in it.className }
|
||||
val simpleClassName = firstOutsideStacktrace.className.substringAfterLast('.')
|
||||
return Tag(removeAnonymousSuffix(simpleClassName))
|
||||
}
|
||||
|
||||
private val ANONYMOUS_CLASS_PATTERN = Pattern.compile("(\\$\\d+)+$") // all "$123" at the end of the class name
|
||||
@Pure
|
||||
private fun removeAnonymousSuffix(tag: String): String {
|
||||
val matcher = ANONYMOUS_CLASS_PATTERN.matcher(tag)
|
||||
return if (matcher.find()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user