-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPythonInterpreter.gd
More file actions
160 lines (142 loc) · 5.08 KB
/
Copy pathPythonInterpreter.gd
File metadata and controls
160 lines (142 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
extends Node
# @onready var program = get_tree().root.get_child(0)
# @onready var python = get_tree().root.get_child(0).get("PythonInterpreter")
var DIR = OS.get_executable_path().get_base_dir() + "/"
var interpreter_path = "python3" # DIR +
var process_ids = []
var watched_pids = {}
var OS_name = OS.get_name()
var delay = 1.0
var time_passed = 0.0
@export var watchdogable = false
signal all_processes_closed
signal interpreter_ready
func _ready():
# Delete log.txt on startup
if OS.has_feature("editor"):
interpreter_path = ProjectSettings.globalize_path("res://python-3.10.11-embed/python.exe")
else:
interpreter_path = DIR + "python-3.10.11-embed/python.exe"
print("Python interpreter path: " + interpreter_path)
interpreter_ready.emit()
func run_script(python_binary, script_path, script_args=[], console=true, watchdog=false):
if python_binary != "":
if python_binary.begins_with("./") or python_binary.begins_with(".\\"):
python_binary = python_binary.replace("./", "")
python_binary = python_binary.replace(".\\", "")
if OS.has_feature("editor"):
python_binary = ProjectSettings.globalize_path("res://" + python_binary)
else:
python_binary = DIR + python_binary
else:
python_binary = interpreter_path
print("Running Python script: " + script_path)
if OS.has_feature("editor"):
script_path = ProjectSettings.globalize_path("res://" + script_path)
else:
script_path = DIR + script_path
var args = [script_path] + script_args
var PID = OS.create_process(python_binary, args, console)
if watchdog:
watched_pids[PID] = [python_binary, args, console, watchdog]
print("Watchdog enabled for process: " + str(PID))
print("Process ID: " + str(PID))
process_ids.append(PID)
return PID
func run_script_from_dir(dir, script_path, console=true, watchdog=false):
print("Running Python script: " + script_path)
if dir.ends_with("/"):
dir = dir.substr(0, dir.length() - 1)
script_path = dir + "/" + script_path
var requirements = dir + "/requirements.txt"
# var args = ["/c", "cd", dir, ";", interpreter_path + " -m pip install -r " + requirements, ";", interpreter_path, module_path]
# print("CMD.exe", args, console)
# print("CMD.exe " + " ".join(args))
# var PID = OS.create_process("CMD.exe", args, console)
var args = ["/d", "cd", dir, ";", interpreter_path, "-m", "pip", "install", "-r", requirements, ";", interpreter_path, script_path]
print("start", args, console)
print("start " + " ".join(args))
var PID = OS.create_process("start", args, console)
if watchdog:
watched_pids[PID] = ["CMD.exe", args, console, watchdog]
print("Watchdog enabled for process: " + str(PID))
print("Process ID: " + str(PID))
process_ids.append(PID)
return PID
func execute_script(script_path):
print("Executing Python script: " + script_path)
if OS.has_feature("editor"):
script_path = ProjectSettings.globalize_path("res://" + script_path)
else:
script_path = DIR + script_path
var args = [script_path]
OS.execute(interpreter_path, args)
func run(command):
print("Running command: " + command)
var args = [command]
var PID = OS.create_process(interpreter_path, args, true)
print("Process ID: " + str(PID))
process_ids.append(PID)
return PID
func install_packages(packages):
print("Installing packages: " + str(packages))
var args = ["-m", "pip", "install"]
for package in packages:
args.append(package)
print(interpreter_path+" ", args)
OS.execute(interpreter_path, args)
func _notification(what):
if what == Node.NOTIFICATION_WM_CLOSE_REQUEST:
for PID in process_ids:
OS.kill(PID)
print("Killed process: " + str(PID))
get_tree().quit()
func _process(delta):
if !watchdogable:
return
time_passed += delta
if time_passed > delay:
time_passed = 0.0
# check if process ids are still running
# print("Checking processes")
for PID in process_ids:
if !OS.is_process_running(PID):
print("Process " + str(PID) + " has exited")
var repos = get_tree().get_nodes_in_group("repository")
if PID in watched_pids:
var interpreter_path_ = watched_pids[PID][0]
var args = watched_pids[PID][1]
var console = watched_pids[PID][2]
var watchdog = watched_pids[PID][3]
print("Restarting process: " + str(PID)+ " with interpreter: " + interpreter_path_ + " and args: " + str(args))
var newPID = OS.create_process(interpreter_path_, args, console)
watched_pids.erase(PID)
for repo in repos:
if repo.PID == PID:
repo.PID = newPID
if watchdog:
watched_pids[newPID] = [interpreter_path_, args, console, watchdog]
print("Watchdog enabled for process: " + str(newPID))
process_ids.append(newPID)
else:
for repo in repos:
if repo.PID == PID:
if repo.active:
repo._stop_repo()
process_ids.erase(PID)
break
if process_ids.size() == 0:
all_processes_closed.emit()
func stop():
for PID in process_ids:
OS.kill(PID)
print("Killed process: " + str(PID))
func stop_PID(PID):
watched_pids.erase(PID)
if PID != null:
OS.kill(PID)
print("Killed process: " + str(PID))
# func _on_l_la_m_acpp_on_connected():
# watchdogable = true
# func _on_timer_timeout():
# watchdogable = true