package kernel.peripherals; import lib.exporter.ExportConfig; import lib.exporter.IExportable; import haxe.ds.ReadOnlyArray; import lib.Color; using tink.CoreApi; abstract BundleMask(Int) from cc.Colors.Color to cc.Colors.Color { public inline function new(i:Int) { this = i; } @:from public static function fromColor(c:Color) { return new BundleMask(c); } @:op(A + B) @:op(A | B) public inline function combine(rhs:BundleMask):BundleMask { return this | rhs; } @:op(A + B) @:op(A | B) public inline function combineWithColor(rhs:Color):BundleMask { return this | rhs; } public function getComponents():ReadOnlyArray { var components:Array = []; var mask = 1; for (i in 0...16) { if ((this & mask) > 0) { components.push(mask); } mask = mask << 1; } return components; } } @:build(macros.Exporter.buildExport()) class Redstone implements IPeripheral implements IExportable { public static inline final TYPE_NAME:String = "redstone"; // TODO: there is technically not a type for redstone. public final onChange:Signal; private final onChangeTrigger:SignalTrigger = Signal.trigger(); private final addr:Side; private var analogInputState:Int; private var bundleInputState:BundleMask; @:allow(kernel.peripherals) private function new(side:Side) { this.addr = side; this.onChange = this.onChangeTrigger.asSignal(); updateState(); KernelEvents.onRedstone.handle(() -> { if ((this.getAnalogInput() != this.analogInputState) || (this.bundleInputState != this.getBundledInput())) { updateState(); this.onChangeTrigger.trigger(null); } }); } public function getAddr():String { return this.addr; } public function getType():String { return TYPE_NAME; } private function updateState() { this.analogInputState = cc.Redstone.getAnalogInput(this.addr); this.bundleInputState = cc.Redstone.getBundledInput(this.addr); } public inline function setOutput(on:Bool):Void { this.analogInputState = 15; cc.Redstone.setOutput(this.addr, on); } @export("output") public inline function getOutput():Bool { return cc.Redstone.getOutput(this.addr); } @export("input") public inline function getInput():Bool { return cc.Redstone.getInput(this.addr); } public inline function setAnalogOutput(strength:Int):Void { this.analogInputState = strength; cc.Redstone.setAnalogOutput(this.addr, strength); } public inline function getAnalogOutput():Int { return cc.Redstone.getAnalogOutput(this.addr); } public inline function getAnalogInput():Int { return cc.Redstone.getAnalogInput(this.addr); } public inline function setBundledOutput(output:BundleMask) { this.bundleInputState = output; cc.Redstone.setBundledOutput(this.addr, output); } public inline function getBundledOutput():BundleMask { return cc.Redstone.getBundledOutput(this.addr); } public inline function getBundledInput():BundleMask { return cc.Redstone.getBundledInput(this.addr); } public inline function testBundledInput(mask:Color):Bool { return cc.Redstone.testBundledInput(this.addr, mask); } }