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;
 | |
| 	}
 | |
| }
 |