Skip to content

Instantly share code, notes, and snippets.

@Vladg24YT
Last active December 31, 2022 07:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vladg24YT/dcbb1ed68658122f21e8edcf32f0db6d to your computer and use it in GitHub Desktop.
Save Vladg24YT/dcbb1ed68658122f21e8edcf32f0db6d to your computer and use it in GitHub Desktop.
Ocelot Brain demo in Java.
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