Skip to content

Commit 829d71e

Browse files
committed
H e l p -
1 parent 432e818 commit 829d71e

File tree

5 files changed

+248
-1
lines changed

5 files changed

+248
-1
lines changed

source/archipelago/ArchPopup.hx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,22 @@ class ArchPopup extends openfl.display.Sprite {
2323
var alphaTween:FlxTween;
2424
var lastScale:Float = 1;
2525
public static var daUnlockSong:String = 'Nothing lol';
26+
public static var instances:yutautil.LimitedArray<ArchPopup> = new yutautil.LimitedArray<ArchPopup>(6);
2627

2728
public function new(name:String, desc:String, ?song:String, ?image:String, ?onFinish:Void->Void)
2829
{
2930
super();
3031

32+
instances.add(this, 'remove_oldest');
33+
34+
for (popup in _popups)
35+
{
36+
if (instances.indexOf(popup) == -1)
37+
{
38+
popup.destroy();
39+
}
40+
}
41+
3142
// bg
3243
graphics.beginFill(FlxColor.BLACK);
3344
graphics.drawRoundRect(0, 0, 420, 130, 16, 16);

source/yutautil/JavaLoop.hx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package yutautil;
2+
3+
import haxe.macro.Context;
4+
import haxe.macro.Expr;
5+
6+
class JavaLoop {
7+
public static macro function transformJavaLoops(expr:Expr):Expr {
8+
return switch (expr) {
9+
case macro for ($v in $it) $body:
10+
// This is already a Haxe-compatible for loop, no transformation needed
11+
expr;
12+
case macro for ($v: $t in $it) $body:
13+
// This is already a Haxe-compatible for loop with type, no transformation needed
14+
expr;
15+
case macro for ($v = $start; $cond; $inc) $body:
16+
// Transform Java-style for loop to Haxe-compatible for loop
17+
var init = $v;
18+
var condition = $cond;
19+
var increment = $inc;
20+
var loopBody = $body;
21+
macro {
22+
{
23+
$init;
24+
while ($condition) {
25+
$loopBody;
26+
$increment;
27+
}
28+
}
29+
};
30+
case _:
31+
// Recursively transform sub-expressions
32+
Context.mapExpr(transformJavaLoops, expr);
33+
}
34+
}
35+
}
36+

source/yutautil/LimitedArray.hx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package yutautil;
2+
3+
class LimitedArray<T> {
4+
private var items:Array<T>;
5+
private var limit:Int;
6+
7+
public function new(limit:Int) {
8+
this.limit = limit;
9+
this.items = [];
10+
}
11+
12+
public function add(item:T, strategy:String = "ignore"):Void {
13+
if (items.length >= limit) {
14+
switch (strategy) {
15+
case "pop":
16+
items.pop();
17+
items.push(item);
18+
case "remove_oldest":
19+
items.shift();
20+
items.push(item);
21+
case "remove_newest":
22+
items.pop();
23+
items.push(item);
24+
case "ignore":
25+
// Do nothing
26+
default:
27+
// Do nothing
28+
}
29+
} else {
30+
items.push(item);
31+
}
32+
}
33+
34+
public function get(index:Int):T {
35+
return items[index];
36+
}
37+
38+
public function size():Int {
39+
return items.length;
40+
}
41+
42+
public function indexOf(item:T):Int {
43+
return items.indexOf(item);
44+
}
45+
46+
public function clear():Void {
47+
items = [];
48+
}
49+
}

source/yutautil/MetaData.hx

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package yutautil;
2+
3+
// import tink.CoreApi.Ref;
4+
import haxe.ds.WeakMap;
5+
import haxe.Timer;
6+
// import haxe.macro.Context;
7+
// import haxe.macro.Expr;
8+
9+
class MetaData {
10+
private static var metaMap:WeakMap<Dynamic, Dynamic> = new WeakMap();
11+
private static var cleanupTimer:Timer = new Timer(60000); // Cleanup every 60 seconds
12+
13+
public static function init():Void {
14+
cleanupTimer.run = cleanup;
15+
}
16+
17+
public static function metadata<T>(variable:T):Dynamic {
18+
if (!metaMap.exists(variable)) {
19+
var meta = {};
20+
metaMap.set(variable, meta);
21+
initializeMeta(variable, meta);
22+
}
23+
return metaMap.get(variable);
24+
}
25+
26+
public static function addMeta<T>(variable:T, metaD:Dynamic):Void {
27+
if (!metaMap.exists(variable)) {
28+
var meta = {};
29+
metaMap.set(variable, meta);
30+
initializeMeta(variable, meta);
31+
}
32+
Reflect.setField(metaMap.get(variable), metaD, metaD);
33+
34+
}
35+
36+
public static function setMeta<T>(variable:T, key:String, value:Dynamic):Void {
37+
if (metaMap.exists(variable)) {
38+
var meta = metaMap.get(variable);
39+
Reflect.setField(meta, key, value);
40+
} else {
41+
throw "No metadata exists for the variable.";
42+
}
43+
}
44+
45+
public static function remMeta<T>(variable:T):Void {
46+
if (metaMap.exists(variable)) {
47+
metaMap.remove(variable);
48+
}
49+
}
50+
51+
private static function initializeMeta<T>(variable:T, meta:Dynamic):Void {
52+
53+
function add(key:String, value:Dynamic):Void {
54+
Reflect.setField(meta, key, value);
55+
}
56+
57+
switch (Type.typeof(variable)) {
58+
case TClass(c): // Maybe not recommended on giant classes or states...
59+
for (field in Type.getInstanceFields(c)) {
60+
if (Reflect.isObject(Reflect.field(c, field))) {
61+
for (stuff in Reflect.fields(Reflect.field(c, field))) {
62+
metadata(Reflect.field(Reflect.field(c, field), stuff));
63+
}
64+
}
65+
else {
66+
metadata(Reflect.field(c, field));
67+
}
68+
}
69+
Reflect.setField(meta, "class", Type.getClassName(c));
70+
Reflect.setField(meta, "super", Type.getClassName(Type.getSuperClass(c)));
71+
case TInt:
72+
// Reflect.setField(meta, "e", Std.int(variable));
73+
74+
case TFloat:
75+
Reflect.setField(meta, "int", Std.int(cast(variable, Float)));
76+
case TBool:
77+
Reflect.setField(meta, "binary", cast(variable, Bool) ? "1" : "0");
78+
// case TString:
79+
// Reflect.setField(meta, "binary", StringTools.hex(Std.parseInt(variable)));
80+
81+
case TFunction:
82+
Reflect.setField(meta, "call", function() {
83+
if (Reflect.isFunction(variable)) {
84+
(cast variable:Void->Void)();
85+
}
86+
});
87+
default:
88+
// Handle other types if necessary
89+
90+
if (variable is String) {
91+
// Reflect.setField(meta, "base64", haxe.crypto.Base64.encode((cast variable : String));
92+
Reflect.setField(meta, "char", (cast variable : String).split(""));
93+
}
94+
if (variable is Array) {
95+
for (thing in cast(variable, Array<Dynamic>)) {
96+
metadata(thing);
97+
}
98+
}
99+
if (variable is haxe.Constraints.IMap) {
100+
for (key in (cast variable:haxe.Constraints.IMap<Dynamic, Dynamic>).keys()) {
101+
metadata(key);
102+
metadata((cast variable:haxe.Constraints.IMap<Dynamic, Dynamic>).get(key));
103+
}
104+
}
105+
}
106+
}
107+
108+
private static function cleanup():Void {
109+
for (key in metaMap.keys()) {
110+
if (key == null) {
111+
metaMap.remove(key);
112+
}
113+
}
114+
}
115+
}
116+
117+
// MetaData.init();

source/yutautil/Sandbox.hx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,27 @@ typedef MethodName = String;
77
typedef CatchFunction = (ErrorType, MethodName, MethodArgs) -> Void;
88
typedef MethodArgs = Array<Dynamic>;
99

10+
/**
11+
* A generic class representing a sandbox environment.
12+
*
13+
*
14+
*
15+
* The sandbox will create a proxy object that will call the methods of the instance
16+
* and catch any errors that may occur. This allows for dealing with less important objects without
17+
* the potential of crashing the entire application, however it will void the ability to easily use type safety.
18+
* @param instance The type of elements this sandbox will handle.
19+
* @param catchFunction A function that will be called when an error occurs. The function will receive the error, the method name and the arguments. If not provided, a default function will be used.
20+
* @param verboseErrors If true, the stack trace will be printed when an error occurs.
21+
*/
1022
class Sandbox<T> {
1123
private var instance:T;
24+
private var proxy:Dynamic;
1225
private var catchFunction:CatchFunction;
1326
private var verboseErrors:Bool;
1427

1528
public function new(instance:T, ?catchFunction:CatchFunction, ?verboseErrors:Bool = false) {
1629
this.instance = instance;
30+
this.proxy = createProxy(instance);
1731
this.catchFunction = catchFunction != null ? catchFunction : defaultCatchFunction;
1832
this.verboseErrors = verboseErrors;
1933
}
@@ -27,6 +41,10 @@ class Sandbox<T> {
2741
}
2842
}
2943

44+
public function pcall():Dynamic {
45+
return proxy;
46+
}
47+
3048
private function defaultCatchFunction(e:ErrorType, method:MethodName, args:MethodArgs):Void {
3149
trace('Error in method: ' + method);
3250
trace('Arguments: ' + args);
@@ -55,7 +73,7 @@ class Sandbox<T> {
5573
}
5674
}
5775
return inst;
58-
}
76+
}
5977

6078
public function unsafeCall(method:MethodName, args:MethodArgs):Dynamic {
6179
return Reflect.callMethod(instance, Reflect.field(instance, method), args);
@@ -72,4 +90,20 @@ class Sandbox<T> {
7290
public function unsafeAccess():Dynamic {
7391
return instance;
7492
}
93+
94+
private function createProxy(instance:T):Dynamic {
95+
var proxy = {};
96+
var fields = Type.getInstanceFields(instance);
97+
for (field in fields) {
98+
var value = Reflect.field(instance, field);
99+
if (Reflect.isFunction(value)) {
100+
Reflect.setField(proxy, field, function(...args) {
101+
return call(field, args);
102+
});
103+
} else {
104+
Reflect.setField(proxy, field, value);
105+
}
106+
}
107+
return proxy;
108+
}
75109
}

0 commit comments

Comments
 (0)