initial commit

This commit is contained in:
2021-12-20 01:55:30 +01:00
commit bd790c1488
38 changed files with 2320 additions and 0 deletions

43
src/util/BuildInfo.hx Normal file
View File

@@ -0,0 +1,43 @@
package util;
/**
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
}
}

111
src/util/Color.hx Normal file
View File

@@ -0,0 +1,111 @@
package util;
import haxe.Exception;
import cc.Colors;
enum Color {
White;
Orange;
Magenta;
LightBlue;
Yellow;
Lime;
Pink;
Gray;
Grey;
LightGray;
LightGrey;
Cyan;
Purple;
Blue;
Brown;
Green;
Red;
Black;
}
class ColorConvert {
public static function colorToCC(color: Color): cc.Colors.Color {
switch color {
case White:
return Colors.white;
case Orange:
return Colors.orange;
case Magenta:
return Colors.magenta;
case LightBlue:
return Colors.lightBlue;
case Yellow:
return Colors.yellow;
case Lime:
return Colors.lime;
case Pink:
return Colors.pink;
case Gray:
return Colors.gray;
case Grey:
return Colors.grey;
case LightGray:
return Colors.lightGray;
case LightGrey:
return Colors.lightGrey;
case Cyan:
return Colors.cyan;
case Purple:
return Colors.purple;
case Blue:
return Colors.blue;
case Brown:
return Colors.brown;
case Green:
return Colors.green;
case Red:
return Colors.red;
case Black:
return Colors.black;
};
}
public static function ccToColor(color: cc.Colors.Color): Color {
switch color {
case 0:
return White;
case 1:
return Orange;
case 2:
return Magenta;
case 3:
return LightBlue;
case 4:
return Yellow;
case 5:
return Lime;
case 6:
return Pink;
case 7:
return Gray;
case 8:
return Grey;
case 9:
return LightGray;
case 10:
return LightGrey;
case 11:
return Cyan;
case 12:
return Purple;
case 13:
return Blue;
case 14:
return Brown;
case 15:
return Green;
case 16:
return Red;
case 17:
return Black;
case _:
throw new Exception("Invalid input");
}
}
}

16
src/util/Debug.hx Normal file
View File

@@ -0,0 +1,16 @@
package util;
import cc.ComputerCraft;
import kernel.Log;
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);
}
}

62
src/util/EventBus.hx Normal file
View File

@@ -0,0 +1,62 @@
package util;
import util.Signal.SignalListner;
class EventBusListner<T> {
@:allow(util.EventBus)
private final signalListner:SignalListner<T>;
@:allow(util.EventBus)
private final eventName:String;
@:allow(util.EventBus)
private function new(signalListner: SignalListner<T>,eventName: String) {
this.signalListner = signalListner;
this.eventName = eventName;
}
}
/**
Generic event handler.
**/
class EventBus<T>{
private var listner: Map<String,Signal<T>> = new Map();
public function new() {
}
public function on(eventName: String, callback: T->Void):EventBusListner<T>{
if (!listner.exists(eventName)){
listner[eventName] = new Signal();
}
var signalListner = listner[eventName].on(callback);
return new EventBusListner(signalListner,eventName);
}
public function once(eventName: String,callback: T->Void):EventBusListner<T> {
if (!listner.exists(eventName)){
listner[eventName] = new Signal();
}
var signalListner = listner[eventName].once(callback);
return new EventBusListner(signalListner,eventName);
}
public function emit(eventName: String, data: Any) {
if (listner.exists(eventName)){
var signal = listner[eventName];
signal.emit(data);
}
}
public function removeListner(id: EventBusListner<T>) {
if (!listner.exists(id.eventName)) {
return;
}
listner[id.eventName].remove(id.signalListner);
}
}

69
src/util/Extender.hx Normal file
View File

@@ -0,0 +1,69 @@
package util;
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/util/MathI.hx Normal file
View File

@@ -0,0 +1,19 @@
package util;
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;
}
}
}

40
src/util/Promise.hx Normal file
View File

@@ -0,0 +1,40 @@
package util;
import haxe.Exception;
/**
JS-like promise class.
**/
class Promise<T> {
private var thenCB: T->Void;
private var errorCB: Exception -> Void;
public function then(cb: (data: T)->Void): Promise<T> {
thenCB = cb;
return this;
}
public function error(cb: (err: Exception)->Void) {
errorCB = cb;
}
public function new(func:(resolve:(T)->Void,reject:(Exception)->Void)->Void) {
try {
func(data -> {
if (thenCB != null){
thenCB(data);
}
},e -> {
if (errorCB != null){
errorCB(e);
}
});
}catch(e:Exception){
if (errorCB != null){
errorCB(e);
}
}
}
}

61
src/util/Signal.hx Normal file
View File

@@ -0,0 +1,61 @@
package util;
interface SignalReadonly<T> {
public function on(cb: T->Void):SignalListner<T>;
public function once(cb: T->Void):SignalListner<T>;
public function remove(id:SignalListner<T>):Void;
}
class SignalListner<T> {
private final callback:T->Void;
@:allow(util.Signal)
private final once:Bool;
@:allow(util.Signal)
private function new(callback: T->Void,?once: Bool = false) {
this.callback = callback;
this.once = once;
}
@:allow(util.Signal)
private function invoke(params: T) {
if (callback != null){
callback(params);
}
}
}
/**
Simple event system for one event type other than EventBus which has multiple events.
**/
class Signal<T> implements SignalReadonly<T>{
public final listner:Array<SignalListner<T>> = new Array();
public function new() {}
public function on(cb: T->Void):SignalListner<T> {
var l = new SignalListner<T>(cb,false);
listner.push(l);
return l;
}
public function once(cb: T->Void):SignalListner<T> {
var l = new SignalListner<T>(cb,true);
listner.push(l);
return l;
}
public function emit(data: T) {
for (cb in listner){
cb.invoke(data);
if (cb.once){
listner.remove(cb);
}
}
}
public function remove(id:SignalListner<T> ) {
listner.remove(id);
}
}

13
src/util/Vec.hx Normal file
View File

@@ -0,0 +1,13 @@
package util;
@: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;
}