another big refactor
This commit is contained in:
42
src/lib/BuildInfo.hx
Normal file
42
src/lib/BuildInfo.hx
Normal file
@@ -0,0 +1,42 @@
|
||||
package lib;
|
||||
|
||||
/**
|
||||
Macros with static information.
|
||||
**/
|
||||
class BuildInfo {
|
||||
/**
|
||||
Get the latest git commit.
|
||||
**/
|
||||
public static macro function getGitCommitHash():haxe.macro.Expr.ExprOf<String> {
|
||||
#if !display
|
||||
var process = new sys.io.Process('git', ['rev-parse', 'HEAD']);
|
||||
if (process.exitCode() != 0) {
|
||||
var message = process.stderr.readAll().toString();
|
||||
var pos = haxe.macro.Context.currentPos();
|
||||
haxe.macro.Context.error("Cannot execute `git rev-parse HEAD`. " + message, pos);
|
||||
}
|
||||
|
||||
// read the output of the process
|
||||
var commitHash:String = process.stdout.readLine();
|
||||
|
||||
// Generates a string expression
|
||||
return macro $v{commitHash};
|
||||
#else
|
||||
// `#if display` is used for code completion. In this case returning an
|
||||
// empty string is good enough; We don't want to call git on every hint.
|
||||
var commitHash:String = "";
|
||||
return macro $v{commitHash};
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
Get the time the file was build.
|
||||
**/
|
||||
public static macro function buildTime():haxe.macro.Expr.ExprOf<Int> {
|
||||
#if !display
|
||||
return macro $v{Math.floor(Date.now().getTime())};
|
||||
#else
|
||||
return macro $v{0};
|
||||
#end
|
||||
}
|
||||
}
|
||||
28
src/lib/Color.hx
Normal file
28
src/lib/Color.hx
Normal file
@@ -0,0 +1,28 @@
|
||||
package lib;
|
||||
|
||||
import kernel.peripherals.Redstone.BundleMask;
|
||||
|
||||
enum abstract Color(Int) from cc.Colors.Color to cc.Colors.Color {
|
||||
var White = 0x1;
|
||||
var Orange = 0x2;
|
||||
var Magenta = 0x4;
|
||||
var LightBlue = 0x8;
|
||||
var Yellow = 0x10;
|
||||
var Lime = 0x20;
|
||||
var Pink = 0x40;
|
||||
var Gray = 0x80;
|
||||
var LightGray = 0x100;
|
||||
var Cyan = 0x200;
|
||||
var Purple = 0x400;
|
||||
var Blue = 0x800;
|
||||
var Brown = 0x1000;
|
||||
var Green = 0x2000;
|
||||
var Red = 0x4000;
|
||||
var Black = 0x8000;
|
||||
|
||||
@:op(A + B)
|
||||
@:op(A | B)
|
||||
public inline function combine(rhs: Color):BundleMask {
|
||||
return this | rhs;
|
||||
}
|
||||
}
|
||||
46
src/lib/Debug.hx
Normal file
46
src/lib/Debug.hx
Normal file
@@ -0,0 +1,46 @@
|
||||
package lib;
|
||||
|
||||
import lua.NativeStringTools;
|
||||
import lib.ui.Canvas;
|
||||
import cc.ComputerCraft;
|
||||
import kernel.Log;
|
||||
#if webconsole
|
||||
import cc.HTTP;
|
||||
import kernel.net.Net;
|
||||
#end
|
||||
|
||||
class Debug {
|
||||
public static function printBuildInfo() {
|
||||
Log.debug("Commit: " + BuildInfo.getGitCommitHash());
|
||||
|
||||
var time:Date = Date.fromTime(BuildInfo.buildTime());
|
||||
|
||||
Log.debug("Build time: " + time.toString());
|
||||
|
||||
Log.debug("CC/MC version:" + ComputerCraft._HOST);
|
||||
}
|
||||
|
||||
public static function printCanvasToConsole(canvas: Canvas) {
|
||||
var lines: Array<String> = [];
|
||||
|
||||
for (pos => pixel in canvas){
|
||||
if (lines[pos.y] == null) {
|
||||
lines[pos.y] = "";
|
||||
}
|
||||
|
||||
if (lines[pos.y].length < pos.x) {
|
||||
lines[pos.y] += NativeStringTools.rep(" ", pos.x - lines[pos.y].length);
|
||||
}
|
||||
|
||||
lines[pos.y] = lines[pos.y].substr(0, pos.x) + pixel.char + lines[pos.y].substr(pos.x + 1);
|
||||
}
|
||||
|
||||
Log.debug("\n" + lines.join("\n"));
|
||||
}
|
||||
|
||||
#if webconsole
|
||||
public static function printWeb(msg:String) {
|
||||
HTTP.request("http://127.0.0.1:8080/"+Net.instance.networkID,msg);
|
||||
}
|
||||
#end
|
||||
}
|
||||
69
src/lib/Extender.hx
Normal file
69
src/lib/Extender.hx
Normal file
@@ -0,0 +1,69 @@
|
||||
package lib;
|
||||
|
||||
import haxe.Exception;
|
||||
|
||||
class LambdaExtender {
|
||||
/**
|
||||
Returns the first element if there are exectly one element present.
|
||||
Throws exception if not.
|
||||
**/
|
||||
static public function single<T>(it:Iterable<T>):T {
|
||||
var elem:T = null;
|
||||
for (t in it) {
|
||||
if (elem != null) {
|
||||
throw new Exception("Multiple elements found");
|
||||
}
|
||||
elem = t;
|
||||
}
|
||||
|
||||
if (elem == null) {
|
||||
throw new Exception("No element found");
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
/**
|
||||
Like `single` but when no element was found return the default value.
|
||||
**/
|
||||
static public function singleOrDefault<T>(it:Iterable<T>, defaultValue:T):T {
|
||||
var elem:T = null;
|
||||
for (t in it) {
|
||||
if (elem != null) {
|
||||
throw new Exception("Multiple elements found");
|
||||
}
|
||||
elem = t;
|
||||
}
|
||||
|
||||
if (elem == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the first element.
|
||||
Throws execption if no first element found.
|
||||
**/
|
||||
static public function first<T>(it:Iterable<T>):T {
|
||||
for (t in it) {
|
||||
return t;
|
||||
}
|
||||
|
||||
throw new Exception("No element found");
|
||||
}
|
||||
|
||||
/**
|
||||
Like `first` only if no first element was found it returns the defalt value.
|
||||
**/
|
||||
static public function firstOrDefault<T>(it:Iterable<T>, defaultValue:T):T {
|
||||
var iter = it.iterator();
|
||||
|
||||
if (iter.hasNext()) {
|
||||
return iter.next();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
19
src/lib/MathI.hx
Normal file
19
src/lib/MathI.hx
Normal file
@@ -0,0 +1,19 @@
|
||||
package lib;
|
||||
|
||||
class MathI {
|
||||
public static function max(a:Int, b:Int):Int {
|
||||
if (a > b) {
|
||||
return a;
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
public static function min(a:Int, b:Int):Int {
|
||||
if (a < b) {
|
||||
return a;
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/lib/ObjMerge.hx
Normal file
24
src/lib/ObjMerge.hx
Normal file
@@ -0,0 +1,24 @@
|
||||
package lib;
|
||||
|
||||
class ObjMerge {
|
||||
public static function merge<T>(obj1:T, obj2:T): T {
|
||||
if (obj1 == null) {
|
||||
return obj2;
|
||||
}
|
||||
|
||||
if (obj2 == null) {
|
||||
return obj1;
|
||||
}
|
||||
|
||||
var rtn:T = Reflect.copy(obj1);
|
||||
var fields = Reflect.fields(obj2);
|
||||
|
||||
for (field in fields) {
|
||||
if (Reflect.getProperty(obj1, field) == null) {
|
||||
Reflect.setProperty(rtn, field, Reflect.getProperty(obj2, field));
|
||||
}
|
||||
}
|
||||
|
||||
return (rtn:T);
|
||||
}
|
||||
}
|
||||
46
src/lib/Pos.hx
Normal file
46
src/lib/Pos.hx
Normal file
@@ -0,0 +1,46 @@
|
||||
package lib;
|
||||
|
||||
import lib.Vec.Vec2;
|
||||
|
||||
/**
|
||||
Reporesents a Point in a 2D `Int` System.
|
||||
Basicly a wrapper for Vec2<Int> with some extra functions.
|
||||
**/
|
||||
@:forward(x,y)
|
||||
abstract Pos(Vec2<Int>) from Vec2<Int> to Vec2<Int>{
|
||||
inline public function new(i:Vec2<Int>) {
|
||||
this = i;
|
||||
}
|
||||
|
||||
@:op(A + B)
|
||||
public function add(rhs: Vec2<Int>):Pos {
|
||||
return new Pos({
|
||||
y: this.y + rhs.y,
|
||||
x: this.x + rhs.x,
|
||||
});
|
||||
}
|
||||
|
||||
@:op(A - B)
|
||||
public function sub(rhs: Vec2<Int>):Pos {
|
||||
return new Pos({
|
||||
y: this.y - rhs.y,
|
||||
x: this.x - rhs.x,
|
||||
});
|
||||
}
|
||||
|
||||
@:op(A * B)
|
||||
public function multiply(rhs: Vec2<Int>): Pos {
|
||||
return new Pos({
|
||||
y: this.y * rhs.y,
|
||||
x: this.x * rhs.x,
|
||||
});
|
||||
}
|
||||
|
||||
@:op(-A)
|
||||
public function negate(): Pos {
|
||||
return new Pos({
|
||||
y: -this.y,
|
||||
x: -this.x,
|
||||
});
|
||||
}
|
||||
}
|
||||
51
src/lib/Pos3.hx
Normal file
51
src/lib/Pos3.hx
Normal file
@@ -0,0 +1,51 @@
|
||||
package lib;
|
||||
|
||||
import lib.Vec.Vec3;
|
||||
|
||||
/**
|
||||
Reporesents a Point in a 3D `Int` System.
|
||||
Basicly a wrapper for Vec3<Int> with some extra functions.
|
||||
`Y` represents the height of the point.
|
||||
**/
|
||||
@:forward(x,y,z)
|
||||
abstract Pos3(Vec3<Int>) from Vec3<Int> to Vec3<Int>{
|
||||
inline public function new(i:Vec3<Int>) {
|
||||
this = i;
|
||||
}
|
||||
|
||||
@:op(A + B)
|
||||
public function add(rhs: Vec3<Int>):Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y + rhs.y,
|
||||
x: this.x + rhs.x,
|
||||
z: this.z + rhs.z
|
||||
});
|
||||
}
|
||||
|
||||
@:op(A - B)
|
||||
public function sub(rhs: Vec3<Int>):Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y - rhs.y,
|
||||
x: this.x - rhs.x,
|
||||
z: this.z - rhs.z
|
||||
});
|
||||
}
|
||||
|
||||
@:op(A * B)
|
||||
public function multiply(rhs: Vec3<Int>): Pos3 {
|
||||
return new Pos3({
|
||||
y: this.y * rhs.y,
|
||||
x: this.x * rhs.x,
|
||||
z: this.z * rhs.z
|
||||
});
|
||||
}
|
||||
|
||||
@:op(-A)
|
||||
public function negate(): Pos3 {
|
||||
return new Pos3({
|
||||
y: -this.y,
|
||||
x: -this.x,
|
||||
z: -this.z
|
||||
});
|
||||
}
|
||||
}
|
||||
31
src/lib/Rect.hx
Normal file
31
src/lib/Rect.hx
Normal file
@@ -0,0 +1,31 @@
|
||||
package lib;
|
||||
|
||||
class Rect {
|
||||
|
||||
private final tr:Pos;
|
||||
private final bl:Pos;
|
||||
|
||||
public function new(p1: Pos,p2:Pos) {
|
||||
this.tr = {
|
||||
x: MathI.max(p1.x,p2.x),
|
||||
y: MathI.max(p1.y,p2.y)
|
||||
};
|
||||
|
||||
this.bl = {
|
||||
x: MathI.min(p1.x,p2.x),
|
||||
y: MathI.min(p1.y,p2.y)
|
||||
};
|
||||
}
|
||||
|
||||
public function getSize(): Int {
|
||||
return (tr.x - bl.x) * (tr.y - bl.y);
|
||||
}
|
||||
|
||||
public function isInside(p: Pos): Bool {
|
||||
return (p.x >= bl.x && p.x <= tr.x) && (p.y >= bl.y && p.y <= tr.y);
|
||||
}
|
||||
|
||||
public function isOutside(p: Pos): Bool {
|
||||
return !this.isInside(p);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package lib;
|
||||
|
||||
import util.Color;
|
||||
import lib.Color;
|
||||
import kernel.ui.TermWriteable;
|
||||
|
||||
/**
|
||||
|
||||
12
src/lib/Vec.hx
Normal file
12
src/lib/Vec.hx
Normal file
@@ -0,0 +1,12 @@
|
||||
package lib;
|
||||
|
||||
@:structInit class Vec2<T> {
|
||||
public final x:T;
|
||||
public final y:T;
|
||||
}
|
||||
|
||||
@:structInit class Vec3<T> {
|
||||
public final x:T;
|
||||
public final y:T;
|
||||
public final z:T;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package lib;
|
||||
package lib.cli;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package lib;
|
||||
package lib.cli;
|
||||
|
||||
import haxe.ds.ReadOnlyArray;
|
||||
|
||||
27
src/lib/observable/DummyObservable.hx
Normal file
27
src/lib/observable/DummyObservable.hx
Normal file
@@ -0,0 +1,27 @@
|
||||
package lib.observable;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class DummyObservable<T> implements Observable<T> {
|
||||
private var value:T;
|
||||
|
||||
private function new(value:T) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public function set(value:T) {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public function get():T {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public function subscribe(callback:Callback<T>):CallbackLink {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function dummy<T>(value: T): Observable<T> {
|
||||
return new DummyObservable<T>(value);
|
||||
}
|
||||
}
|
||||
9
src/lib/observable/Observable.hx
Normal file
9
src/lib/observable/Observable.hx
Normal file
@@ -0,0 +1,9 @@
|
||||
package lib.observable;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
interface Observable<T> {
|
||||
public function set(value:T): Void;
|
||||
public function get():T;
|
||||
public function subscribe(callback:Callback<T>):CallbackLink;
|
||||
}
|
||||
56
src/lib/observable/ObservableArray.hx
Normal file
56
src/lib/observable/ObservableArray.hx
Normal file
@@ -0,0 +1,56 @@
|
||||
package lib.observable;
|
||||
|
||||
class ObservableArray<T> extends ObservableValue<Array<T>> {
|
||||
public function new(value: Array<T>) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
public function insert(pos: Int, x: T):Void {
|
||||
this.value.insert(pos,x);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function pop(): Null<T> {
|
||||
var poped = this.pop();
|
||||
this.callbacks.invoke(this.value);
|
||||
return poped;
|
||||
}
|
||||
|
||||
public function push(x: T):Int {
|
||||
var i = this.value.push(x);
|
||||
this.callbacks.invoke(this.value);
|
||||
return i;
|
||||
}
|
||||
|
||||
public function remove(x: T): Bool {
|
||||
var b = this.value.remove(x);
|
||||
this.callbacks.invoke(this.value);
|
||||
return b;
|
||||
}
|
||||
|
||||
public function resize(len: Int) {
|
||||
this.value.resize(len);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function reverse() {
|
||||
this.value.reverse();
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function shift(): Null<T> {
|
||||
var e = this.value.shift();
|
||||
this.callbacks.invoke(this.value);
|
||||
return e;
|
||||
}
|
||||
|
||||
public function sort(f:(T, T) -> Int):Void {
|
||||
this.value.sort(f);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
|
||||
public function unshift(x: T):Void {
|
||||
this.value.unshift(x);
|
||||
this.callbacks.invoke(this.value);
|
||||
}
|
||||
}
|
||||
28
src/lib/observable/ObservableValue.hx
Normal file
28
src/lib/observable/ObservableValue.hx
Normal file
@@ -0,0 +1,28 @@
|
||||
package lib.observable;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class ObservableValue<T> implements Observable<T> {
|
||||
private var value:T;
|
||||
private var callbacks:CallbackList<T> = new CallbackList();
|
||||
|
||||
public function new(value:T) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public function set(value:T) {
|
||||
if (value != this.value) {
|
||||
this.value = value;
|
||||
callbacks.invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
public function get():T {
|
||||
return value;
|
||||
}
|
||||
|
||||
public function subscribe(callback:Callback<T>):CallbackLink {
|
||||
callback.invoke(value);
|
||||
return callbacks.add(callback);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package lib.turtle;
|
||||
|
||||
import util.Pos;
|
||||
import util.Pos3;
|
||||
import lib.Pos;
|
||||
import lib.Pos3;
|
||||
import kernel.turtle.Turtle;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class TurtleExecuter {
|
||||
|
||||
@@ -10,7 +10,6 @@ import lua.NativeStringTools;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
|
||||
/**
|
||||
Save a set of turtle instructions to a string and execute them.
|
||||
**/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package lib.ui;
|
||||
|
||||
import util.Pos;
|
||||
import util.Rect;
|
||||
import lib.Pos;
|
||||
import lib.Rect;
|
||||
import kernel.ui.Pixel;
|
||||
|
||||
abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> from Array<Array<Pixel>>{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package lib.ui;
|
||||
|
||||
import util.Pos;
|
||||
import util.Vec.Vec2;
|
||||
import lib.Pos;
|
||||
import kernel.ButtonType;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
typedef UIEvents = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package lib.ui.reactive;
|
||||
|
||||
import util.Pos;
|
||||
import lib.Pos;
|
||||
import util.Rect;
|
||||
import util.ObservableArray;
|
||||
import util.Vec.Vec2;
|
||||
import lib.Vec.Vec2;
|
||||
|
||||
class ListElement extends UIElement {
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ package lib.ui.reactive;
|
||||
|
||||
import lib.ui.Dimensions;
|
||||
import util.ObjMerge;
|
||||
import util.Pos;
|
||||
import lib.Pos;
|
||||
import util.Observable;
|
||||
import util.Color;
|
||||
import util.Vec.Vec2;
|
||||
import lib.Color;
|
||||
import lib.Vec.Vec2;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package lib.ui.reactive;
|
||||
|
||||
import util.Debug;
|
||||
import util.Vec.Vec2;
|
||||
import util.Pos;
|
||||
import lib.Debug;
|
||||
import lib.Vec.Vec2;
|
||||
import lib.Pos;
|
||||
|
||||
class TurtleController extends UIElement {
|
||||
|
||||
@@ -21,8 +21,6 @@ class TurtleController extends UIElement {
|
||||
canvas.combine(addButton("F"),{x:1,y:1});
|
||||
canvas.combine(addButton("F"),{x:5,y:2});
|
||||
|
||||
Debug.printCanvasToConsole(canvas);
|
||||
|
||||
return canvas;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package lib.ui.reactive;
|
||||
|
||||
import util.ObjMerge;
|
||||
import util.Pos;
|
||||
import util.Rect;
|
||||
import util.Vec.Vec2;
|
||||
import lib.Pos;
|
||||
import lib.Rect;
|
||||
import lib.Vec.Vec2;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user