diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt index 42b288ab3..8c75057fb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidResearchType.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.android import com.google.common.collect.ImmutableList +import com.google.common.collect.ImmutableSet import it.unimi.dsi.fastutil.objects.ObjectArraySet import net.minecraft.network.chat.Component import net.minecraft.network.chat.ComponentContents @@ -10,6 +11,9 @@ import ru.dbotthepony.mc.otm.TranslatableComponent import ru.dbotthepony.mc.otm.capability.AndroidCapability import ru.dbotthepony.mc.otm.getKeyNullable import ru.dbotthepony.mc.otm.registry.MRegistry +import java.util.* +import kotlin.collections.HashSet +import kotlin.collections.RandomAccess fun interface AndroidResearchFactory { fun factory(type: AndroidResearchType<*>, capability: AndroidCapability): R @@ -55,6 +59,59 @@ private fun findAllChildren( return add } +class ListSet(private val list: ImmutableList) : List, Set, RandomAccess { + constructor(list: Collection) : this(ImmutableList.copyOf(list)) + + private val set: ImmutableSet by lazy { ImmutableSet.copyOf(list) } + + override val size: Int + get() = list.size + + override fun contains(element: T): Boolean { + return set.contains(element) + } + + override fun containsAll(elements: Collection): Boolean { + return set.containsAll(elements) + } + + override fun get(index: Int): T { + return list[index] + } + + override fun indexOf(element: T): Int { + return list.indexOf(element) + } + + override fun isEmpty(): Boolean { + return list.isEmpty() + } + + override fun iterator(): Iterator { + return list.iterator() + } + + override fun lastIndexOf(element: T): Int { + return list.lastIndexOf(element) + } + + override fun listIterator(): ListIterator { + return list.listIterator() + } + + override fun listIterator(index: Int): ListIterator { + return list.listIterator(index) + } + + override fun spliterator(): Spliterator { + return list.spliterator() + } + + override fun subList(fromIndex: Int, toIndex: Int): List { + return list.subList(fromIndex, toIndex) + } +} + open class AndroidResearchType( protected val factory: AndroidResearchFactory ) { @@ -97,6 +154,8 @@ open class AndroidResearchType( * * C specify both B and A as it's prerequisites, [flatPrerequisites] will contain only B, when [definedPrerequisites] will contain * both B and A + * + * Returns list which also doubles as set (for contains method). */ val flatPrerequisites: List> by lazy { val parentPrerequisites = findPrerequisites(definedPrerequisites) @@ -108,14 +167,16 @@ open class AndroidResearchType( } } - builder.build() + ListSet(builder.build()) } /** * All prerequisite research, including indirect ones + * + * Returns list which also doubles as set (for contains method). */ val allPrerequisites: List> by lazy { - ImmutableList.copyOf(findAllPrerequisites(flatPrerequisites)) + ListSet(findAllPrerequisites(flatPrerequisites)) } /** @@ -130,6 +191,8 @@ open class AndroidResearchType( * * C is blocked by A * * Both C and B specify A as it's blockers, [flatBlocking] will contain only B, because C is blocked by A through B. + * + * Returns list which also doubles as set (for contains method). */ val flatBlocking: List> by lazy { val list = ImmutableList.builder>() @@ -151,11 +214,13 @@ open class AndroidResearchType( } } - return@lazy list.build() + ListSet(list.build()) } /** * All research directly unlocked by this research. + * + * Returns list which also doubles as set (for contains method). */ val flatUnlocks: List> by lazy { val list = ImmutableList.builder>() @@ -166,14 +231,32 @@ open class AndroidResearchType( } } - return@lazy list.build() + ListSet(list.build()) } /** * All research unlocked by this research, including indirect ones + * + * Returns list which also doubles as set (for contains method). */ val allUnlocks: List> by lazy { - ImmutableList.copyOf(findAllChildren(flatUnlocks)) + ListSet(findAllChildren(flatUnlocks)) + } + + /** + * All research blocked by this research, including indirect ones. + * + * Returns list which also doubles as set (for contains method) + */ + val allBlocking: List> by lazy { + val set = HashSet>() + + for (research in flatBlocking) { + set.add(research) + set.addAll(research.allUnlocks) + } + + ListSet(set) } fun factory(capability: AndroidCapability) = factory.factory(this, capability)