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