diff --git a/project.godot b/project.godot index 39b7d3f..f2de314 100644 --- a/project.godot +++ b/project.godot @@ -28,12 +28,18 @@ _global_script_classes=[ { "class": "Shell", "language": "GDScript", "path": "res://scenes/shell.gd" +}, { +"base": "Node", +"class": "ShellCommand", +"language": "GDScript", +"path": "res://scenes/shell_command.gd" } ] _global_script_class_icons={ "Chapter": "", "Level": "", "LevelRepo": "", -"Shell": "" +"Shell": "", +"ShellCommand": "" } [application] diff --git a/scenes/shell.gd b/scenes/shell.gd index be1cc53..93eb139 100644 --- a/scenes/shell.gd +++ b/scenes/shell.gd @@ -18,8 +18,30 @@ func cd(dir): # Run a shell command given as a string. Run this if you're interested in the # output of the command. func run(command, crash_on_fail=true): + var shell_command = ShellCommand.new() + shell_command.command = command + shell_command.crash_on_fail = crash_on_fail + + run_async_thread(shell_command) + exit_code = shell_command.exit_code + return shell_command.output + +func run_async(command, crash_on_fail=true): + var shell_command = ShellCommand.new() + shell_command.command = command + shell_command.crash_on_fail = crash_on_fail + + var _thread = Thread.new() + _thread.start(self, "run_async_thread", shell_command) + + return shell_command + +func run_async_thread(shell_command): var debug = false + var command = shell_command.command + var crash_on_fail = shell_command.crash_on_fail + if debug: print("$ %s" % command) @@ -64,8 +86,9 @@ func run(command, crash_on_fail=true): if debug: print(result["output"]) - exit_code = result["exit_code"] - return result["output"] + shell_command.output = result["output"] + shell_command.exit_code = result["exit_code"] + shell_command.emit_signal("done") func _shell_binary(): if _os == "X11" or _os == "OSX": @@ -75,25 +98,25 @@ func _shell_binary(): else: helpers.crash("Unsupported OS: %s" % _os) -var _t -func run_async(command): - _t = Thread.new() - _t.start(self, "run_async_thread", command) - -func run_async_thread(command): - var port = 1000 + (randi() % 1000) - var s = TCP_Server.new() - s.listen(port) - var _pid = OS.execute("ncat", ["127.0.0.1", str(port), "-c", command], false, [], true) - while not s.is_connection_available(): - pass - var c = s.take_connection() - while c.get_status() == StreamPeerTCP.STATUS_CONNECTED: - read_from(c) - OS.delay_msec(1000/30) - read_from(c) - c.disconnect_from_host() - s.stop() +#var _t +#func run_async(command): +# _t = Thread.new() +# _t.start(self, "run_async_thread", command) +# +#func run_async_thread(command): +# var port = 1000 + (randi() % 1000) +# var s = TCP_Server.new() +# s.listen(port) +# var _pid = OS.execute("ncat", ["127.0.0.1", str(port), "-c", command], false, [], true) +# while not s.is_connection_available(): +# pass +# var c = s.take_connection() +# while c.get_status() == StreamPeerTCP.STATUS_CONNECTED: +# read_from(c) +# OS.delay_msec(1000/30) +# read_from(c) +# c.disconnect_from_host() +# s.stop() func read_from(c): var total_available = c.get_available_bytes() diff --git a/scenes/shell_command.gd b/scenes/shell_command.gd new file mode 100644 index 0000000..38c2010 --- /dev/null +++ b/scenes/shell_command.gd @@ -0,0 +1,9 @@ +extends Node +class_name ShellCommand + +signal done + +var command +var output +var exit_code +var crash_on_fail = true diff --git a/scenes/terminal.gd b/scenes/terminal.gd index d73047a..cc927f5 100644 --- a/scenes/terminal.gd +++ b/scenes/terminal.gd @@ -2,8 +2,6 @@ extends Control signal command_done -var thread - var history_position = 0 var git_commands = ["add", "am", "archive", "bisect", "branch", "bundle", "checkout", "cherry-pick", "citool", "clean", "clone", "commit", "describe", "diff", "fetch", "format-patch", "gc", "gitk", "grep", "gui", "init", "log", "merge", "mv", "notes", "pull", "push", "range-diff", "rebase", "reset", "restore", "revert", "rm", "shortlog", "show", "sparse-checkout", "stash", "status", "submodule", "switch", "tag", "worktree", "config", "fast-export", "fast-import", "filter-branch", "mergetool", "pack-refs", "prune", "reflog", "remote", "repack", "replace", "annotate", "blame", "bugreport", "count-objects", "difftool", "fsck", "gitweb", "help", "instaweb", "merge-tree", "rerere", "show-branch", "verify-commit", "verify-tag", "whatchanged", "archimport", "cvsexportcommit", "cvsimport", "cvsserver", "imap-send", "p", "quiltimport", "request-pull", "send-email", "svn", "apply", "checkout-index", "commit-graph", "commit-tree", "hash-object", "index-pack", "merge-file", "merge-index", "mktag", "mktree", "multi-pack-index", "pack-objects", "prune-packed", "read-tree", "symbolic-ref", "unpack-objects", "update-index", "update-ref", "write-tree", "cat-file", "cherry", "diff-files", "diff-index", "diff-tree", "for-each-ref", "get-tar-commit-id", "ls-files", "ls-remote", "ls-tree", "merge-base", "name-rev", "pack-redundant", "rev-list", "rev-parse", "show-index", "show-ref", "unpack-file", "var", "verify-pack", "daemon", "fetch-pack", "http-backend", "send-pack", "update-server-info", "check-attr", "check-ignore", "check-mailmap", "check-ref-format", "column", "credential", "credential-cache", "credential-store", "fmt-merge-msg", "interpret-trailers", "mailinfo", "mailsplit", "merge-one-file", "patch-id", "sh-i", "sh-setup"] @@ -77,20 +75,11 @@ func send_command(command): input.editable = false completions.hide() - - if thread != null: - thread.wait_to_finish() - thread = Thread.new() - thread.start(self, "run_command_in_a_thread", command) -func send_command_async(command): - input.text = "" - $TCPServer.send(command+"\n") - -func run_command_in_a_thread(command): - var o = repository.shell.run(command, false) + var cmd = repository.shell.run_async(command, false) + yield(cmd, "done") - if repository.shell.exit_code == 0: + if cmd.exit_code == 0: $OkSound.pitch_scale = rand_range(0.8, 1.2) $OkSound.play() else: @@ -99,14 +88,14 @@ func run_command_in_a_thread(command): input.text = "" input.editable = true - if o.length() <= 1000: - output.text = output.text + "$ " + command + "\n" + o + if cmd.output.length() <= 1000: + output.text = output.text + "$ " + command + "\n" + cmd.output else: - $Pager/Text.text = o + $Pager/Text.text = cmd.output $Pager.popup() emit_signal("command_done") - + func receive_output(text): output.text += text repository.update_everything()