LNXSDK/Kha/Sources/kha/netsync/EntityBuilder.hx
2025-01-22 16:18:30 +01:00

207 lines
4.3 KiB
Haxe

package kha.netsync;
import haxe.io.Bytes;
import haxe.macro.Context;
import haxe.macro.Expr;
class EntityBuilder {
public static var nextId: Int = 0;
macro static public function build(): Array<Field> {
var fields = Context.getBuildFields();
var isBaseEntity = false;
for (i in Context.getLocalClass().get().interfaces) {
var intf = i.t.get();
if (intf.module == "kha.netsync.Entity") {
isBaseEntity = true;
break;
}
}
var receive = macro {};
var send = macro {};
if (!isBaseEntity) {
receive = macro {
offset += super._receive(offset, bytes);
};
send = macro {
offset += super._send(offset, bytes);
};
}
var index: Int = 0;
for (field in fields) {
var replicated = false;
for (meta in field.meta) {
if (meta.name == "replicate" || meta.name == "replicated") {
replicated = true;
break;
}
}
if (!replicated)
continue;
switch (field.kind) {
case FVar(t, e):
var fieldname = field.name;
switch (t) {
case TPath(p):
switch (p.name) {
case "Int":
send = macro {
$send;
bytes.setInt32(offset + $v{index}, this.$fieldname);
};
receive = macro {
$receive;
this.$fieldname = bytes.getInt32(offset + $v{index});
};
index += 4;
case "Float":
send = macro {
$send;
bytes.setDouble(offset + $v{index}, this.$fieldname);
};
receive = macro {
$receive;
this.$fieldname = bytes.getDouble(offset + $v{index});
};
index += 8;
case "Bool":
send = macro {
$send;
bytes.set(offset + $v{index}, this.$fieldname ? 1 : 0);
};
receive = macro {
$receive;
this.$fieldname = bytes.get(offset + $v{index}) == 1 ? true : false;
};
index += 1;
}
default:
}
default:
}
}
send = macro {
$send;
return $v{index};
};
receive = macro {
$receive;
return $v{index};
};
fields.push({
name: "_send",
doc: null,
meta: [],
access: isBaseEntity ? [APublic] : [APublic, AOverride],
kind: FFun({
ret: Context.toComplexType(Context.getType("Int")),
params: null,
expr: send,
args: [
{
value: null,
type: Context.toComplexType(Context.getType("Int")),
opt: null,
name: "offset"
},
{
value: null,
type: Context.toComplexType(Context.getType("haxe.io.Bytes")),
opt: null,
name: "bytes"
}
]
}),
pos: Context.currentPos()
});
fields.push({
name: "_receive",
doc: null,
meta: [],
access: isBaseEntity ? [APublic] : [APublic, AOverride],
kind: FFun({
ret: Context.toComplexType(Context.getType("Int")),
params: null,
expr: receive,
args: [
{
value: null,
type: Context.toComplexType(Context.getType("Int")),
opt: null,
name: "offset"
},
{
value: null,
type: Context.toComplexType(Context.getType("haxe.io.Bytes")),
opt: null,
name: "bytes"
}
]
}),
pos: Context.currentPos()
});
fields.push({
name: "_id",
doc: null,
meta: [],
access: isBaseEntity ? [APublic] : [APublic, AOverride],
kind: FFun({
ret: Context.toComplexType(Context.getType("Int")),
params: null,
expr: macro {return __id;},
args: []
}),
pos: Context.currentPos()
});
var size = macro {
return $v{index};
};
if (!isBaseEntity) {
size = macro {
return super._size() + $v{index};
};
}
fields.push({
name: "_size",
doc: null,
meta: [],
access: isBaseEntity ? [APublic] : [APublic, AOverride],
kind: FFun({
ret: Context.toComplexType(Context.getType("Int")),
params: null,
expr: size,
args: []
}),
pos: Context.currentPos()
});
if (isBaseEntity) {
fields.push({
name: "__id",
doc: null,
meta: [],
access: [APublic],
kind: FVar(macro : Int, macro kha.netsync.EntityBuilder.nextId++),
pos: Context.currentPos()
});
}
return fields;
}
}