@@ -10,6 +10,12 @@ open class UniqueMap() {
10
10
// 750 including deprecated, and EnumMap creates a N-sized array where N is the number of objects in the enum
11
11
private val typedUniqueMap = EnumMap <UniqueType , ArrayList <Unique >>(UniqueType ::class .java)
12
12
13
+ // Another memory-speed tradeoff - enumset is super fast and also super cheap, but it's not nothing
14
+ // This is used to speed up triggered uniques - in other words, when we want to find all uniques with a certain modifier.
15
+ // Rather than mapping all uniques thus triggered, this just stores whether any unique has that trigger -
16
+ // because most of the time is spent iterating on uniques, in uniquemaps that have no such trigger in the first place!
17
+ private val triggerEnumSet = EnumSet .noneOf(UniqueType ::class .java)
18
+
13
19
constructor (uniques: Sequence <Unique >) : this () {
14
20
addUniques(uniques.asIterable())
15
21
}
@@ -21,10 +27,11 @@ open class UniqueMap() {
21
27
val existingArrayList = innerUniqueMap[unique.placeholderText]
22
28
if (existingArrayList != null ) existingArrayList.add(unique)
23
29
else innerUniqueMap[unique.placeholderText] = arrayListOf (unique)
24
-
30
+
25
31
if (unique.type == null ) return
26
32
if (typedUniqueMap[unique.type] != null ) return
27
33
typedUniqueMap[unique.type] = innerUniqueMap[unique.placeholderText]
34
+ triggerEnumSet.add(unique.type)
28
35
}
29
36
30
37
/* * Calls [addUnique] on each item from [uniques] */
@@ -36,20 +43,20 @@ open class UniqueMap() {
36
43
val existingArrayList = innerUniqueMap[unique.placeholderText]
37
44
existingArrayList?.remove(unique)
38
45
}
39
-
46
+
40
47
fun clear () {
41
48
innerUniqueMap.clear()
42
49
typedUniqueMap.clear()
43
50
}
44
-
51
+
45
52
// Pure functions
46
-
53
+
47
54
fun hasUnique (uniqueType : UniqueType , state : StateForConditionals = StateForConditionals .EmptyState ) =
48
55
getUniques(uniqueType).any { it.conditionalsApply(state) && ! it.isTimedTriggerable }
49
56
50
57
fun hasUnique (uniqueTag : String , state : StateForConditionals = StateForConditionals .EmptyState ) =
51
58
getUniques(uniqueTag).any { it.conditionalsApply(state) && ! it.isTimedTriggerable }
52
-
59
+
53
60
fun hasTagUnique (tagUnique : String ) =
54
61
innerUniqueMap.containsKey(tagUnique)
55
62
@@ -62,7 +69,7 @@ open class UniqueMap() {
62
69
?.asSequence()
63
70
? : emptySequence()
64
71
65
- fun getMatchingUniques (uniqueType : UniqueType , state : StateForConditionals = StateForConditionals .EmptyState ) =
72
+ fun getMatchingUniques (uniqueType : UniqueType , state : StateForConditionals = StateForConditionals .EmptyState ) =
66
73
getUniques(uniqueType)
67
74
// Same as .filter | .flatMap, but more cpu/mem performant (7.7 GB vs ?? for test)
68
75
.flatMap {
@@ -83,8 +90,8 @@ open class UniqueMap() {
83
90
else -> it.getMultiplied(state)
84
91
}
85
92
}
86
-
87
- fun hasMatchingUnique (uniqueType : UniqueType , state : StateForConditionals = StateForConditionals .EmptyState ) =
93
+
94
+ fun hasMatchingUnique (uniqueType : UniqueType , state : StateForConditionals = StateForConditionals .EmptyState ) =
88
95
getUniques(uniqueType).any { it.conditionalsApply(state) }
89
96
90
97
fun hasMatchingUnique (uniqueTag : String , state : StateForConditionals = StateForConditionals .EmptyState ) =
@@ -95,11 +102,12 @@ open class UniqueMap() {
95
102
96
103
fun getTriggeredUniques (trigger : UniqueType , stateForConditionals : StateForConditionals ,
97
104
triggerFilter : (Unique ) -> Boolean = { true }): Sequence <Unique > {
105
+ if (! triggerEnumSet.contains(trigger)) return emptySequence() // Common case - no such unique exists
98
106
return getAllUniques().filter { unique ->
99
107
unique.getModifiers(trigger).any(triggerFilter) && unique.conditionalsApply(stateForConditionals)
100
108
}.flatMap { it.getMultiplied(stateForConditionals) }
101
109
}
102
-
110
+
103
111
companion object {
104
112
val EMPTY = UniqueMap ()
105
113
}
0 commit comments