Last active
December 31, 2022 07:07
-
-
Save Vladg24YT/dcbb1ed68658122f21e8edcf32f0db6d to your computer and use it in GitHub Desktop.
Ocelot Brain demo in Java.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.ocelot; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import org.apache.logging.log4j.LogManager; | |
import scala.Function1; | |
import scala.collection.immutable.Seq; | |
import totoro.ocelot.brain.Ocelot; | |
import totoro.ocelot.brain.entity.CPU; | |
import totoro.ocelot.brain.entity.Case; | |
import totoro.ocelot.brain.entity.EEPROM; | |
import totoro.ocelot.brain.entity.GraphicsCard; | |
import totoro.ocelot.brain.entity.HDDManaged; | |
import totoro.ocelot.brain.entity.Memory; | |
import totoro.ocelot.brain.entity.Redstone; | |
import totoro.ocelot.brain.entity.Redstone.Tier1; | |
import totoro.ocelot.brain.entity.Screen; | |
import totoro.ocelot.brain.entity.machine.Arguments; | |
import totoro.ocelot.brain.entity.traits.Entity; | |
import totoro.ocelot.brain.entity.traits.Environment; | |
import totoro.ocelot.brain.event.BeepEvent; | |
import totoro.ocelot.brain.event.BeepPatternEvent; | |
import totoro.ocelot.brain.event.Event; | |
import totoro.ocelot.brain.event.EventBus; | |
import totoro.ocelot.brain.event.FileSystemActivityEvent; | |
import totoro.ocelot.brain.event.MachineCrashEvent; | |
import totoro.ocelot.brain.event.TextBufferSetBackgroundColorEvent; | |
import totoro.ocelot.brain.event.TextBufferSetEvent; | |
import totoro.ocelot.brain.event.TextBufferSetForegroundColorEvent; | |
import totoro.ocelot.brain.loot.Loot; | |
import totoro.ocelot.brain.nbt.NBTTagCompound; | |
import totoro.ocelot.brain.nbt.persistence.PersistableString; | |
import totoro.ocelot.brain.util.Tier; | |
import totoro.ocelot.brain.workspace.Workspace; | |
/** | |
* Ocelot Brain 0.6.5 demo, rewritten in Java 8 | |
* | |
* Original Demo: | |
* https://gitlab.com/cc-ru/ocelot/ocelot-brain/-/blob/master/src/main/scala/totoro/ocelot/demo/Demo.scala | |
* | |
* @author VladTheMountain | |
*/ | |
public class OcelotDemo { | |
Case computer; | |
// Uncomment the line below if you're creating a custom EEPROM | |
//@SuppressWarnings("unchecked") | |
public OcelotDemo() throws IOException, InterruptedException { | |
System.out.println("Hi! We are testing Ocelot brains here. Join in!"); | |
/** | |
* We can pass here a custom org.apache.logging.log4j.Logger: | |
* `Ocelot.initialize(logger)` | |
*/ | |
Ocelot.initialize(); | |
/** | |
* All things inside of Ocelot usually are grouped by workspaces. | |
* Workspace is like 'world' in Minecraft. It has it's own timeflow, | |
* it's own name, random numbers generator and a list of entities | |
* ('blocks' and 'items' in Minecraft). Workspace can be serialized to | |
* an NBT tag, and then restored back from it. Workspace is also | |
* responsible for the lifecycle of all its entities. | |
* | |
* For things to work correctly, you will usually add new entities to | |
* some workspace. Entities then will be managed by this workspace. | |
* Entities still can form connections between workspaces, and exchange | |
* data. | |
*/ | |
Workspace workspace = new Workspace(Files.createTempDirectory("ocelot-1")); | |
/** | |
* Now we create a new entity - computer case. Straight off we add it to | |
* the workspace. | |
*/ | |
computer = workspace.add(new Case(Tier.Four())); | |
/** | |
* Computer components do not need to be added to the workspace | |
* explicitly, because they are added to the Case internal inventory | |
* (and the case is added to the workspace). | |
*/ | |
CPU cpu = new CPU(Tier.Three()); | |
computer.add(cpu); | |
GraphicsCard gpu = new GraphicsCard(Tier.Three()); | |
computer.add(gpu); | |
Memory memory = new Memory(Tier.Six()); | |
computer.add(memory); | |
Tier1 redstone = new Redstone.Tier1(); | |
computer.add(redstone); | |
/** | |
* When creating a new hard drive, you can specify its address. If you | |
* will leave it `null`, then new random UUID will be used. | |
*/ | |
HDDManaged hdd = new HDDManaged(Tier.One()); | |
computer.add(hdd); | |
/** | |
* Custom EEPROM can be created like this: | |
* | |
*/ | |
/*EEPROM eeprom = new EEPROM(); | |
eeprom.set(computer.machine(), new Arguments((Seq<Object>) Arrays.asList("\nlocal gpu = component.proxy((component.list(\"gpu\", true)()))" | |
+ "\nlocal fs" | |
+ "\n" | |
+ "\nfor address in component.list(\"filesystem\", true) do" | |
+ "\n if component.invoke(address, \"getLabel\") == \"init\" then" | |
+ "\n fs = component.proxy(address)" | |
+ "\n break" | |
+ "\n end" | |
+ "\nend" | |
+ "\n" | |
+ "\nassert(fs, \"no init filesystem found\")" | |
+ "\n" | |
+ "\ngpu.bind((component.list(\"screen\", true)()))" | |
+ "\ngpu.set(1, 1, \"Running script from [59aef805]/init.lua\")" | |
+ "\n" | |
+ "\nlocal w, h = gpu.getResolution()" | |
+ "\n" | |
+ "\nlocal file = fs.open(\"/init.lua\", \"r\")" | |
+ "\n" | |
+ "\nlocal chunk = assert(load(function()" | |
+ "\n return fs.read(file, math.huge)" | |
+ "\nend, \"/init.lua\", \"t\"))" | |
+ "\n" | |
+ "\nfs.close(file)" | |
+ "\ngpu.fill(1, 1, w, h, \" \")" | |
+ "\n" | |
+ "\nlocal returnValues = table.pack(xpcall(chunk, debug.traceback, ...))" | |
+ "\nlocal success = table.remove(returnValues, 1)" | |
+ "\n" | |
+ "\nif not success then" | |
+ "\n error(returnValues[1], 0)" | |
+ "\nelse" | |
+ "\n local data = {}" | |
+ "\n" | |
+ "\n for i = 1, returnValues.n, 1 do" | |
+ "\n table.insert(data, tostring(returnValues[i]))" | |
+ "\n end" | |
+ "\n" | |
+ "\n gpu.set(1, 1, table.concat(data, \", \"))" | |
+ "\nend" | |
+ "\n" | |
+ "\ncomputer.shutdown()".getBytes("UTF-8")))); | |
eeprom.setLabel(computer.machine(), new Arguments((Seq<Object>) new ArrayList<>(Arrays.asList("Test BIOS".getBytes())))); | |
computer.add(eeprom);*/ | |
computer.add(Loot.OpenOsEEPROM().create()); | |
computer.add(Loot.OpenOsFloppy().create()); | |
Screen screen = workspace.add(new Screen(Tier.One())); | |
computer.connect(screen); | |
/** | |
* Here we add some custom NBT data to the computer. This data needs to | |
* implement the Persistable trait. | |
*/ | |
computer.setCustomData(new PersistableString("xxx")); | |
// register some event listeners | |
EventBus.listenTo(BeepEvent.class, (Event e) -> { | |
BeepEvent event = (BeepEvent) e; | |
System.out.println("[EVENT] Beep (address = " + event.address() + ", frequency = " + event.frequency() + ", duration = " + event.duration() + ")"); | |
return null; | |
}); | |
EventBus.listenTo(BeepPatternEvent.class, (Event e) -> { | |
BeepPatternEvent event = (BeepPatternEvent) e; | |
System.out.println("[EVENT] Beep (address = " + event.address() + ", pattern = " + event.pattern() + "})"); | |
return null; | |
}); | |
EventBus.listenTo(MachineCrashEvent.class, (Event e) -> { | |
MachineCrashEvent event = (MachineCrashEvent) e; | |
System.out.println("[EVENT] Machine crash! (address = " + event.address() + " , " + event.message() + ")"); | |
return null; | |
}); | |
EventBus.listenTo(FileSystemActivityEvent.class, (Event e) -> { | |
FileSystemActivityEvent event = (FileSystemActivityEvent) e; | |
System.out.println("[EVENT] Filesystem activity (address = " + event.address() + ")"); | |
return null; | |
}); | |
EventBus.listenTo(TextBufferSetEvent.class, (Event e) -> { | |
TextBufferSetEvent event = (TextBufferSetEvent) e; | |
System.out.println("[EVENT] Text buffer set (address = " + event.address() + "), " + event.x() + "), " + event.y() + "), " + event.value() + ", " + event.vertical() + ")"); | |
return null; | |
}); | |
EventBus.listenTo(TextBufferSetForegroundColorEvent.class, (Event e) -> { | |
TextBufferSetForegroundColorEvent event = (TextBufferSetForegroundColorEvent) e; | |
System.out.println("[EVENT] Foreground color changed (address = " + event.address() + ", " + event.color() + ")"); | |
return null; | |
}); | |
EventBus.listenTo(TextBufferSetBackgroundColorEvent.class, (Event e) -> { | |
TextBufferSetBackgroundColorEvent event = (TextBufferSetBackgroundColorEvent) e; | |
System.out.println("[EVENT] Background color changed (address = " + event.address() + ", " + event.color() + ")"); | |
return null; | |
}); | |
/** | |
* The computer can be turned on or off. By defaults it is turned off. | |
*/ | |
computer.turnOn(); | |
/** | |
* The `computer.machine.isRunning` flag will tell you, if the computer | |
* is still operational, or had it crashed or stopped the execution | |
* otherwise. | |
*/ | |
while (workspace.getIngameTime() < 20) { | |
/** | |
* The `update()` method of workspace will update all components in | |
* each registered network, that need to be updated. These are | |
* usually computers or network cards. | |
*/ | |
workspace.update(); | |
/** | |
* 50 milliseconds is the duration of standard Minecraft tick. You | |
* can speed the simulation up or slow it down by changing this | |
* value. | |
*/ | |
Thread.sleep(50); | |
} | |
/** | |
* Make a snapshot ot the system. You need to use an existing NBT | |
* compound tag (or create a new one). | |
*/ | |
System.out.println("... Creating snapshot ..."); | |
NBTTagCompound nbt = new NBTTagCompound(); | |
workspace.save(nbt); | |
System.out.println(nbt); | |
System.out.println("... Loading snapshot ..."); | |
/** | |
* Load workspace from snapshot | |
*/ | |
Workspace loadedWorkspace = new Workspace(Files.createTempDirectory("ocelot-2")); | |
loadedWorkspace.load(nbt); | |
loadedWorkspace.getEntitiesIter().toList().foreach((Entity v1) -> { // One can use a lambda expression | |
Environment env = null; | |
if (v1 instanceof Environment) { | |
env = (Environment) v1; | |
System.out.println("Loaded.Entity.Address: " + env.node().address()); | |
} | |
return env; | |
}); | |
computer = null; | |
loadedWorkspace.getEntitiesIter().toList().foreach(new Function1<Entity, Case>() { // Or an anonymous inner class | |
@Override | |
public Case apply(Entity v1) { | |
Case comp = null; | |
if (v1 instanceof Case) { | |
computer = (Case) v1; | |
} | |
return comp; | |
} | |
}); | |
if (computer != null) { | |
System.out.println("Successfully loaded the snapshot. Continuing the execution..."); | |
} | |
while (loadedWorkspace.getIngameTime() < 100) { | |
loadedWorkspace.update(); | |
Thread.sleep(50); | |
} | |
System.out.println("... Creating snapshot ..."); | |
nbt = new NBTTagCompound(); | |
loadedWorkspace.save(nbt); | |
System.out.println(nbt); | |
System.out.println("... Turning the computer off ..."); | |
computer.turnOff(); | |
/** | |
* Necessary to successfully complete multi-threaded saving operation, | |
* and finalize other Ocelot tasks. | |
*/ | |
Ocelot.shutdown(); | |
} | |
public static void main(String args[]) { | |
try { | |
new OcelotDemo(); | |
} catch (IOException | InterruptedException ex) { | |
Logger.getLogger(OcelotDemo.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment