diff --git a/src/main/java/li/cil/oc/api/machine/Architecture.java b/src/main/java/li/cil/oc/api/machine/Architecture.java index 96614eba2..d25fcb02a 100644 --- a/src/main/java/li/cil/oc/api/machine/Architecture.java +++ b/src/main/java/li/cil/oc/api/machine/Architecture.java @@ -148,7 +148,22 @@ public interface Architecture { */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) - static @interface Name { + @interface Name { String value(); } + + /** + * Architectures flagged with this annotation can potentially run without + * any additional memory installed in the computer. + *

+ * Use this to allow assembly of devices such as microcontrollers without + * any memory being installed in them while your architecture is being + * used by the CPU being installed. Note to actually make the machine + * start up you only need to always return true from + * {@link #recomputeMemory}. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + @interface NoMemoryRequirements { + } } diff --git a/src/main/scala/li/cil/oc/common/template/Template.scala b/src/main/scala/li/cil/oc/common/template/Template.scala index 2e1e59a53..45a0f369d 100644 --- a/src/main/scala/li/cil/oc/common/template/Template.scala +++ b/src/main/scala/li/cil/oc/common/template/Template.scala @@ -9,6 +9,7 @@ import li.cil.oc.api.driver.item.Container import li.cil.oc.api.driver.item.Inventory import li.cil.oc.api.driver.item.Memory import li.cil.oc.api.driver.item.Processor +import li.cil.oc.api.machine.Architecture import li.cil.oc.common.Slot import li.cil.oc.common.Tier import net.minecraft.inventory.IInventory @@ -40,10 +41,11 @@ abstract class Template { val hasCase = caseTier(inventory) != Tier.None val hasCPU = this.hasCPU(inventory) val hasRAM = this.hasRAM(inventory) + val requiresRAM = this.requiresRAM(inventory) val complexity = this.complexity(inventory) val maxComplexity = this.maxComplexity(inventory) - val valid = hasCase && hasCPU && hasRAM && complexity <= maxComplexity + val valid = hasCase && hasCPU && (hasRAM || !requiresRAM) && complexity <= maxComplexity val progress = if (!hasCPU) Localization.Assembler.InsertCPU @@ -56,7 +58,7 @@ abstract class Template { warnings += Localization.Assembler.Warning(name) } } - if (warnings.length > 0) { + if (warnings.nonEmpty) { warnings.prepend(Localization.Assembler.Warnings) } @@ -80,6 +82,15 @@ abstract class Template { case _ => false }) + protected def requiresRAM(inventory: IInventory) = !(0 until inventory.getSizeInventory). + map(inventory.getStackInSlot). + exists(stack => api.Driver.driverFor(stack, hostClass) match { + case driver: Processor => + val architecture = driver.architecture(stack) + architecture != null && architecture.getAnnotation(classOf[Architecture.NoMemoryRequirements]) != null + case _ => false + }) + protected def hasComponent(name: String)(inventory: IInventory) = exists(inventory, stack => Option(api.Items.get(stack)) match { case Some(descriptor) => descriptor.name == name case _ => false