Made Multithreading Better
This commit is contained in:
parent
13a22ff182
commit
5c8eb765ad
@ -185,6 +185,13 @@ def link_objects(obj_files, link_dirs, libs):
|
|||||||
log(f"[ERROR] {' '.join(cmd)}\n{e.stderr.decode()}")
|
log(f"[ERROR] {' '.join(cmd)}\n{e.stderr.decode()}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
import math
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
def build():
|
def build():
|
||||||
build_start = time.time()
|
build_start = time.time()
|
||||||
banner("🚀 Building Project")
|
banner("🚀 Building Project")
|
||||||
@ -194,7 +201,66 @@ def build():
|
|||||||
link_dirs, libs, extra_includes = resolve_packages()
|
link_dirs, libs, extra_includes = resolve_packages()
|
||||||
all_includes = INCLUDE_DIRS + extra_includes
|
all_includes = INCLUDE_DIRS + extra_includes
|
||||||
|
|
||||||
compile_tasks = []
|
compile_tasks = {}
|
||||||
|
status = {}
|
||||||
|
status_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
last_status_snapshot = {}
|
||||||
|
|
||||||
|
def print_status():
|
||||||
|
with print_lock:
|
||||||
|
# Avoid redrawing if nothing changed
|
||||||
|
snapshot = {k: v for k, v in status.items() if v == "compiling"}
|
||||||
|
if snapshot == last_status_snapshot:
|
||||||
|
return
|
||||||
|
last_status_snapshot.clear()
|
||||||
|
last_status_snapshot.update(snapshot)
|
||||||
|
|
||||||
|
# Clear panel area only, not entire terminal
|
||||||
|
term_size = shutil.get_terminal_size((80, 20))
|
||||||
|
max_name_len = 24
|
||||||
|
grid_cols = max(1, term_size.columns // (max_name_len + 6))
|
||||||
|
|
||||||
|
active = list(snapshot.keys())
|
||||||
|
rows = math.ceil(len(active) / grid_cols)
|
||||||
|
grid = [[""] * grid_cols for _ in range(rows)]
|
||||||
|
|
||||||
|
for i, src in enumerate(active):
|
||||||
|
col = i % grid_cols
|
||||||
|
row = i // grid_cols
|
||||||
|
name = src.name[:max_name_len].ljust(max_name_len)
|
||||||
|
grid[row][col] = f"[🔧] {name}"
|
||||||
|
|
||||||
|
# Draw status block
|
||||||
|
sys.stdout.write("\033[s") # Save cursor
|
||||||
|
sys.stdout.write(f"\033[1;1H") # Move to top-left
|
||||||
|
sys.stdout.write("\033[0J") # Clear below
|
||||||
|
print(color(f"🔨 Compiling ({len(active)} jobs)...", Colors.OKCYAN))
|
||||||
|
for row in grid:
|
||||||
|
if any(cell.strip() for cell in row):
|
||||||
|
print(" ".join(row))
|
||||||
|
print(f"\n{color('⏱ Elapsed:', Colors.GRAY)} {time.time() - build_start:.1f}s")
|
||||||
|
sys.stdout.write("\033[u") # Restore cursor
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def compile_and_track(source, obj):
|
||||||
|
with status_lock:
|
||||||
|
status[source] = "compiling"
|
||||||
|
print_status()
|
||||||
|
|
||||||
|
result = compile_source(source, obj, all_includes)
|
||||||
|
|
||||||
|
with status_lock:
|
||||||
|
status.pop(source, None)
|
||||||
|
print_status()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
with ThreadPoolExecutor() as executor:
|
with ThreadPoolExecutor() as executor:
|
||||||
for source in cpp_files:
|
for source in cpp_files:
|
||||||
obj = obj_path(source)
|
obj = obj_path(source)
|
||||||
@ -213,23 +279,27 @@ def build():
|
|||||||
break
|
break
|
||||||
|
|
||||||
if needs_build:
|
if needs_build:
|
||||||
compile_tasks.append(executor.submit(compile_source, source, obj, all_includes))
|
future = executor.submit(compile_and_track, source, obj)
|
||||||
else:
|
compile_tasks[future] = source
|
||||||
with print_lock:
|
|
||||||
print(f"\r{color('👌 Up-to-date:', Colors.GRAY)} {source}{' ' * 20}", end="", flush=True)
|
|
||||||
|
|
||||||
obj_files.append(obj)
|
obj_files.append(obj)
|
||||||
|
|
||||||
for task in as_completed(compile_tasks):
|
print_status()
|
||||||
if not task.result():
|
|
||||||
|
for future in as_completed(compile_tasks):
|
||||||
|
if not future.result():
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print()
|
banner("📦 Linking")
|
||||||
link_objects(obj_files, link_dirs, libs)
|
link_objects(obj_files, link_dirs, libs)
|
||||||
|
|
||||||
banner("✅ Build Complete")
|
banner("✅ Build Complete")
|
||||||
print(color(f"⏱ Build time: {time.time() - build_start:.2f}s", Colors.OKCYAN))
|
print(color(f"⏱ Build time: {time.time() - build_start:.2f}s", Colors.OKCYAN))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
build()
|
build()
|
||||||
if TARGET.exists():
|
if TARGET.exists():
|
||||||
@ -280,7 +350,7 @@ if __name__ == "__main__":
|
|||||||
try:
|
try:
|
||||||
if "clean" in sys.argv:
|
if "clean" in sys.argv:
|
||||||
clean()
|
clean()
|
||||||
if "clear" in sys.argv:
|
elif "clear" in sys.argv:
|
||||||
clean()
|
clean()
|
||||||
elif "run" in sys.argv:
|
elif "run" in sys.argv:
|
||||||
run()
|
run()
|
||||||
|
Loading…
Reference in New Issue
Block a user