소스 검색

Move hxd.net.RemoteConsole to hide

see #1267
Yuxiao Mao 7 달 전
부모
커밋
3cf175e91b
1개의 변경된 파일0개의 추가작업 그리고 281개의 파일을 삭제
  1. 0 281
      hxd/net/RemoteConsole.hx

+ 0 - 281
hxd/net/RemoteConsole.hx

@@ -1,281 +0,0 @@
-package hxd.net;
-
-/**
-	A simple socket-based local communication channel,
-	aim at communicate between 2 programs (e.g. Hide and a HL game).
-
-	Usage:
-	```haxe
-	var rcmd = new hxd.net.RemoteConsole();
-	// rcmd.log = (msg) -> logToUI(msg);
-	// rcmd.logError = (msg) -> logErrorToUI(msg);
-	rcmd.registerCommands(handler);
-	rcmd.connect(); // or rcmd.startServer()
-	rc.sendCommand("log", "Hello!", function(r) {});
-	```
- */
-@:keep
-@:rtti
-class RemoteConsole {
-	public static var DEFAULT_HOST : String = "127.0.0.1";
-	public static var DEFAULT_PORT : Int = 40001;
-
-	var UID : Int = 0;
-	public var host : String;
-	public var port : Int;
-	var sock : Socket;
-	var cSocks : Array<Socket>;
-	var waitReply : Map<Int, Dynamic->Void>;
-
-	public function new( ?port : Int, ?host : String ) {
-		this.host = host ?? DEFAULT_HOST;
-		this.port = port ?? DEFAULT_PORT;
-		registerCommands(this);
-	}
-
-	public function startServer() {
-		close();
-		sock = new Socket();
-		sock.onError = function(msg) {
-			logError("Socket Error: " + msg);
-			close();
-		}
-		cSocks = [];
-		sock.bind(host, port, function(s) {
-			cSocks.push(s);
-			s.onError = function(msg) {
-				logError("Client error: " + msg);
-				if( s != null )
-					s.close();
-				if( s != null && cSocks != null ) {
-					cSocks.remove(s);
-				}
-			}
-			s.onData = () -> handleOnData(s);
-			log("Client connected");
-		}, 1);
-		log('Server started at $host:$port');
-	}
-
-	public function connect( ?onConnected : Bool -> Void ) {
-		close();
-		sock = new Socket();
-		sock.onError = function(msg) {
-			logError("Socket Error: " + msg);
-			close();
-			if( onConnected != null )
-				onConnected(false);
-		}
-		sock.onData = () -> handleOnData(sock);
-		sock.connect(host, port, function() {
-			log("Connected to server");
-			if( onConnected != null )
-				onConnected(true);
-		});
-		log('Connecting to $host:$port');
-	}
-
-	public function close() {
-		if( sock != null ) {
-			sock.close();
-			sock = null;
-		}
-		if( cSocks != null ) {
-			for( s in cSocks )
-				s.close();
-			cSocks = null;
-		}
-		UID = 0;
-		waitReply = [];
-	}
-
-	public function isConnected() {
-		return sock != null;
-	}
-
-	public dynamic function log( msg : String ) {
-		trace(msg);
-	}
-
-	public dynamic function logError( msg : String ) {
-		trace('[Error] $msg');
-	}
-
-	public function sendCommand( cmd : String, ?args : Dynamic, ?onResult : Dynamic -> Void ) {
-		var id = ++UID;
-		waitReply.set(id, onResult);
-		sendData(cmd, args, id);
-	}
-
-	function sendData( cmd : String, args : Dynamic, id : Int ) {
-		var obj = { cmd : cmd, args : args, id : id};
-		var bytes = haxe.io.Bytes.ofString(haxe.Json.stringify(obj) + "\n");
-		if( cSocks != null ) {
-			for( cs in cSocks ) {
-				cs.out.writeBytes(bytes, 0, bytes.length);
-			}
-		} else {
-			sock.out.writeBytes(bytes, 0, bytes.length);
-		}
-	}
-
-	function handleOnData( s : Socket ) {
-		var str = s.input.readLine().toString();
-		var obj = try { haxe.Json.parse(str); } catch (e) { logError("Parse error: " + e); null; };
-		if( obj == null || obj.id == null ) {
-			return;
-		}
-		var id : Int = obj.id;
-		if( id <= 0 ) {
-			var onResult = waitReply.get(-id);
-			waitReply.remove(-id);
-			if( onResult != null ) {
-				onResult(obj.args);
-			}
-		} else {
-			onCommand(obj.cmd, obj.args, (result) -> sendData(null, result, -id));
-		}
-	}
-
-	function onCommand( cmd : String, args : Dynamic, onDone : Dynamic -> Void ) : Void {
-		if( cmd == null )
-			return;
-		var command = commands.get(cmd);
-		if( command == null ) {
-			logError("Unsupported command " + cmd);
-			return;
-		}
-		command(args, onDone);
-	}
-
-	// ----- Commands -----
-
-	var commands = new Map<String, (args:Dynamic, onDone:Dynamic->Void) -> Void>();
-
-	/**
-		register a single command f.
-		`args` can be null, or an object that can be parse from/to json.
-		`onDone(result)` must be call when `f` finished, and `result` can be null or a json serializable object.
-	 */
-	public function registerCommand( name : String, f : (args:Dynamic, onDone:Dynamic->Void) -> Void ) {
-		commands.set(name, f);
-	}
-
-	/**
-		Register functions marked with `@cmd` in instance `o` as command handler (class of `o` needs `@:rtti` and `@:keep`).
-		This is done with `Reflect` and `registerCommand`, `onDone` call are inserted automatically when necessary.
-		Function name will be used as `cmd` key (and alias name if `@cmd("aliasname")`),
-		if multiple function use the same name, only the latest registered is taken into account.
-
-		Supported `@cmd` function signature:
-		``` haxe
-		@cmd function foo() : Dynamic {}
-		@cmd function foo(args : Dynamic) : Dynamic {}
-		@cmd function foo(onDone : Dynamic->Void) : Void {}
-		@cmd function foo(args : Dynamic, onDone : Dynamic->Void) : Void {}
-		```
-	 */
-	public function registerCommands( o : Dynamic ) {
-		function regRec( cl : Dynamic ) {
-			if( !haxe.rtti.Rtti.hasRtti(cl) )
-				return;
-			var rtti = haxe.rtti.Rtti.getRtti(cl);
-			for( field in rtti.fields ) {
-				var cmd = null;
-				for( m in field.meta ) {
-					if( m.name == "cmd" ) {
-						cmd = m;
-						break;
-					}
-				}
-				if( cmd != null ) {
-					switch( field.type ) {
-						case CFunction(args, ret):
-							var name = field.name;
-							var func = Reflect.field(o, field.name);
-							var f = null;
-							if( args.length == 0 ) {
-								f = (args, onDone) -> onDone(Reflect.callMethod(o, func, []));
-							} else if( args.length == 1 && args[0].t.match(CFunction(_,_))) {
-								f = (args, onDone) -> Reflect.callMethod(o, func, [onDone]);
-							} else if( args.length == 1 ) {
-								f = (args, onDone) -> onDone(Reflect.callMethod(o, func, [args]));
-							} else if( args.length == 2 && args[1].t.match(CFunction(_,_)) ) {
-								f = (args, onDone) -> Reflect.callMethod(o, func, [args, onDone]);
-							} else {
-								logError("Invalid @cmd, found: " + args);
-								continue;
-							}
-							registerCommand(name, f);
-							if( cmd.params.length == 1 ) {
-								var alias = StringTools.trim(StringTools.replace(cmd.params[0], "\"", ""));
-								registerCommand(alias, f);
-							}
-						default:
-					}
-				}
-			}
-		}
-		var cl = Type.getClass(o);
-		while( cl != null ) {
-			regRec(cl);
-			cl = Type.getSuperClass(cl);
-		}
-	}
-
-	@cmd("log") function logCmd( args : Dynamic ) {
-		log("[>] " + args);
-	}
-
-	@cmd function cwd() {
-		return Sys.getCwd();
-	}
-
-	@cmd function programPath() {
-		return Sys.programPath();
-	}
-
-#if hl
-	@cmd function dump( args : { file : String } ) {
-		hl.Gc.major();
-		hl.Gc.dumpMemory(args?.file);
-		if( hxd.res.Resource.LIVE_UPDATE ) {
-			var msg = "hxd.res.Resource.LIVE_UPDATE is on, you may want to disable it for mem dumps; RemoteConsole can also impact memdumps.";
-			logError(msg);
-			sendCommand("log", msg);
-		}
-	}
-
-	@cmd function prof( args : { action : String, samples : Int, delay_ms : Int }, onDone : Dynamic -> Void ) {
-		function doProf( args ) {
-			switch( args.action ) {
-			case "start":
-				hl.Profile.event(-7, "" + (args.samples > 0 ? args.samples : 10000)); // setup
-				hl.Profile.event(-3); // clear data
-				hl.Profile.event(-5); // resume all
-			case "resume":
-				hl.Profile.event(-5); // resume all
-			case "pause":
-				hl.Profile.event(-4); // pause all
-			case "dump":
-				hl.Profile.event(-6); // save dump
-				hl.Profile.event(-4); // pause all
-				hl.Profile.event(-3); // clear data
-			default:
-				sendCommand("log", "Missing argument action for prof");
-			}
-		}
-		if( args == null ) {
-			onDone(null);
-		} else if( args.delay_ms > 0 ) {
-			haxe.Timer.delay(function() {
-				doProf(args);
-				onDone(null);
-			}, args.delay_ms);
-		} else {
-			doProf(args);
-			onDone(null);
-		}
-	}
-#end
-}