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