forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			288 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| package kha.netsync;
 | |
| 
 | |
| import haxe.macro.Context;
 | |
| import haxe.macro.Expr.Field;
 | |
| 
 | |
| class ControllerBuilder {
 | |
| 	public static var nextId: Int = 0;
 | |
| 
 | |
| 	macro static public function build(): Array<Field> {
 | |
| 		var fields = Context.getBuildFields();
 | |
| 
 | |
| 		#if (!kha_server && (kha_html5 || kha_kore))
 | |
| 		{
 | |
| 			var funcindex = 0;
 | |
| 			for (field in fields) {
 | |
| 				var input = false;
 | |
| 				for (meta in field.meta) {
 | |
| 					if (meta.name == "input") {
 | |
| 						input = true;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 				if (!input)
 | |
| 					continue;
 | |
| 
 | |
| 				switch (field.kind) {
 | |
| 					case FFun(f):
 | |
| 						var size = 4;
 | |
| 						for (arg in f.args) {
 | |
| 							switch (arg.type) {
 | |
| 								case TPath(p):
 | |
| 									switch (p.name) {
 | |
| 										case "Int":
 | |
| 											size += 4;
 | |
| 										case "String":
 | |
| 											size += 1;
 | |
| 										case "Float":
 | |
| 											size += 8;
 | |
| 										case "Bool":
 | |
| 											size += 1;
 | |
| 										case "KeyCode":
 | |
| 											size += 1;
 | |
| 									}
 | |
| 								default:
 | |
| 							}
 | |
| 						}
 | |
| 
 | |
| 						var expr = macro @:mergeBlock {
 | |
| 							var bytes = haxe.io.Bytes.alloc($v{size});
 | |
| 							bytes.setInt32(0, $v{funcindex});
 | |
| 						};
 | |
| 						var index: Int = 4;
 | |
| 						for (arg in f.args) {
 | |
| 							switch (arg.type) {
 | |
| 								case TPath(p):
 | |
| 									switch (p.name) {
 | |
| 										case "Int":
 | |
| 											var argname = arg.name;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												bytes.setInt32($v{index}, $i{argname});
 | |
| 											};
 | |
| 											index += 4;
 | |
| 										case "String":
 | |
| 											var argname = arg.name;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												bytes.set($v{index}, $i{argname}.charCodeAt(0));
 | |
| 											};
 | |
| 											index += 1;
 | |
| 										case "Float":
 | |
| 											var argname = arg.name;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												bytes.setDouble($v{index}, $i{argname});
 | |
| 											};
 | |
| 											index += 8;
 | |
| 										case "Bool":
 | |
| 											var argname = arg.name;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												bytes.set($v{index}, $i{argname} ?1:0);
 | |
| 											};
 | |
| 											index += 1;
 | |
| 										case "KeyCode":
 | |
| 											var argname = arg.name;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												bytes.set($v{index}, $i{argname});
 | |
| 											};
 | |
| 											index += 1;
 | |
| 									}
 | |
| 								default:
 | |
| 							}
 | |
| 						}
 | |
| 						var original = f.expr;
 | |
| 						expr = macro {
 | |
| 							if (kha.netsync.Session.the() != null) {
 | |
| 								$expr;
 | |
| 								kha.netsync.Session.the().sendControllerUpdate(_id(), bytes);
 | |
| 							}
 | |
| 							$original;
 | |
| 						};
 | |
| 						f.expr = expr;
 | |
| 					default:
 | |
| 				}
 | |
| 				++funcindex;
 | |
| 			}
 | |
| 		}
 | |
| 		#end
 | |
| 
 | |
| 		// macros failing everywhere but in JavaScript?
 | |
| 		#if (kha_server || kha_html5 || kha_kore)
 | |
| 		var receive = macro @:mergeBlock {
 | |
| 			var funcindex = bytes.getInt32(0);
 | |
| 		};
 | |
| 		{
 | |
| 			var funcindex = 0;
 | |
| 			for (field in fields) {
 | |
| 				var input = false;
 | |
| 				for (meta in field.meta) {
 | |
| 					if (meta.name == "input") {
 | |
| 						input = true;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 				if (!input)
 | |
| 					continue;
 | |
| 
 | |
| 				switch (field.kind) {
 | |
| 					case FFun(f):
 | |
| 						var expr = macro {};
 | |
| 						var index: Int = 4;
 | |
| 						var varindex: Int = 0;
 | |
| 						for (arg in f.args) {
 | |
| 							switch (arg.type) {
 | |
| 								case TPath(p):
 | |
| 									switch (p.name) {
 | |
| 										case "Int":
 | |
| 											var argname = arg.name;
 | |
| 											var varname = "input" + varindex;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												var $varname:Int = bytes.getInt32($v{index});
 | |
| 											};
 | |
| 											index += 4;
 | |
| 										case "String":
 | |
| 											var argname = arg.name;
 | |
| 											var varname = "input" + varindex;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												var $varname:String = String.fromCharCode(bytes.get($v{index}));
 | |
| 											};
 | |
| 											index += 1;
 | |
| 										case "Float":
 | |
| 											var argname = arg.name;
 | |
| 											var varname = "input" + varindex;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												var $varname:Float = bytes.getDouble($v{index});
 | |
| 											};
 | |
| 											index += 8;
 | |
| 										case "Bool":
 | |
| 											var argname = arg.name;
 | |
| 											var varname = "input" + varindex;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												var $varname:Bool = bytes.get($v{index}) != 0;
 | |
| 											};
 | |
| 											index += 1;
 | |
| 										case "KeyCode":
 | |
| 											var argname = arg.name;
 | |
| 											var varname = "input" + varindex;
 | |
| 											expr = macro @:mergeBlock {
 | |
| 												$expr;
 | |
| 												var $varname:kha.input.KeyCode = cast bytes.get($v{index});
 | |
| 											};
 | |
| 											index += 1;
 | |
| 									}
 | |
| 								default:
 | |
| 							}
 | |
| 							++varindex;
 | |
| 						}
 | |
| 						switch (varindex) {
 | |
| 							case 1:
 | |
| 								var funcname = field.name;
 | |
| 								receive = macro @:mergeBlock {
 | |
| 									$receive;
 | |
| 									if (funcindex == $v{funcindex}) {
 | |
| 										$expr;
 | |
| 										$i{funcname}(input0);
 | |
| 										return;
 | |
| 									}
 | |
| 								};
 | |
| 							case 2:
 | |
| 								var funcname = field.name;
 | |
| 								receive = macro @:mergeBlock {
 | |
| 									$receive;
 | |
| 									if (funcindex == $v{funcindex}) {
 | |
| 										$expr;
 | |
| 										$i{funcname}(input0, input1);
 | |
| 										return;
 | |
| 									}
 | |
| 								};
 | |
| 							case 3:
 | |
| 								var funcname = field.name;
 | |
| 								receive = macro @:mergeBlock {
 | |
| 									$receive;
 | |
| 									if (funcindex == $v{funcindex}) {
 | |
| 										$expr;
 | |
| 										$i{funcname}(input0, input1, input2);
 | |
| 										return;
 | |
| 									}
 | |
| 								};
 | |
| 							case 4:
 | |
| 								var funcname = field.name;
 | |
| 								receive = macro @:mergeBlock {
 | |
| 									$receive;
 | |
| 									if (funcindex == $v{funcindex}) {
 | |
| 										$expr;
 | |
| 										$i{funcname}(input0, input1, input2, input3);
 | |
| 										return;
 | |
| 									}
 | |
| 								};
 | |
| 							case 5:
 | |
| 								var funcname = field.name;
 | |
| 								receive = macro @:mergeBlock {
 | |
| 									$receive;
 | |
| 									if (funcindex == $v{funcindex}) {
 | |
| 										$expr;
 | |
| 										$i{funcname}(input0, input1, input2, input3, input4);
 | |
| 										return;
 | |
| 									}
 | |
| 								};
 | |
| 						}
 | |
| 					default:
 | |
| 				}
 | |
| 				++funcindex;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		fields.push({
 | |
| 			name: "_receive",
 | |
| 			doc: null,
 | |
| 			meta: [],
 | |
| 			access: [APublic, AOverride],
 | |
| 			kind: FFun({
 | |
| 				ret: null,
 | |
| 				params: null,
 | |
| 				expr: receive,
 | |
| 				args: [
 | |
| 					{
 | |
| 						value: null,
 | |
| 						type: Context.toComplexType(Context.getType("haxe.io.Bytes")),
 | |
| 						opt: null,
 | |
| 						name: "bytes"
 | |
| 					}
 | |
| 				]
 | |
| 			}),
 | |
| 			pos: Context.currentPos()
 | |
| 		});
 | |
| 		#else
 | |
| 		fields.push({
 | |
| 			name: "_receive",
 | |
| 			doc: null,
 | |
| 			meta: [],
 | |
| 			access: [APublic, AOverride],
 | |
| 			kind: FFun({
 | |
| 				ret: null,
 | |
| 				params: null,
 | |
| 				expr: macro {},
 | |
| 				args: [
 | |
| 					{
 | |
| 						value: null,
 | |
| 						type: Context.toComplexType(Context.getType("haxe.io.Bytes")),
 | |
| 						opt: null,
 | |
| 						name: "bytes"
 | |
| 					}
 | |
| 				]
 | |
| 			}),
 | |
| 			pos: Context.currentPos()
 | |
| 		});
 | |
| 		#end
 | |
| 
 | |
| 		return fields;
 | |
| 	}
 | |
| }
 |