207 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			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;
 | 
						|
	}
 | 
						|
}
 |