194 lines
4.6 KiB
Bash
Executable file
194 lines
4.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
|
GODOT_DIR="$ROOT/godot-desktop"
|
|
TRAY_DIR="$ROOT/services/tray"
|
|
BRIDGE_DIR="$ROOT/services/bridge"
|
|
GODOT="flatpak run --user org.godotengine.Godot"
|
|
PIDFILE="$ROOT/.godot.pid"
|
|
TRAY_PIDFILE="$ROOT/.tray.pid"
|
|
BRIDGE_PIDFILE="$ROOT/.bridge.pid"
|
|
|
|
cmd_start() {
|
|
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
|
|
echo "Already running (pid $(cat "$PIDFILE"))"
|
|
return 1
|
|
fi
|
|
|
|
# 1. Bridge (pub/sub relay for vision events)
|
|
if [ -f "$BRIDGE_DIR/chobit_bridge.py" ]; then
|
|
python3 "$BRIDGE_DIR/chobit_bridge.py" &
|
|
echo $! > "$BRIDGE_PIDFILE"
|
|
echo "Started bridge (pid $!)"
|
|
fi
|
|
|
|
# 2. Godot + tray
|
|
setsid $GODOT --path "$GODOT_DIR" &
|
|
echo $! > "$PIDFILE"
|
|
echo "Started Godot (pid $!)"
|
|
|
|
if [ -f "$TRAY_DIR/chobit_tray.py" ]; then
|
|
python3 "$TRAY_DIR/chobit_tray.py" &
|
|
echo $! > "$TRAY_PIDFILE"
|
|
echo "Started tray (pid $!)"
|
|
fi
|
|
}
|
|
|
|
cmd_stop() {
|
|
# Stop tray
|
|
if [ -f "$TRAY_PIDFILE" ]; then
|
|
local tray_pid
|
|
tray_pid=$(cat "$TRAY_PIDFILE" 2>/dev/null)
|
|
if [ -n "$tray_pid" ] && kill -0 "$tray_pid" 2>/dev/null; then
|
|
kill "$tray_pid" 2>/dev/null && echo "Stopped tray (pid $tray_pid)" || true
|
|
fi
|
|
rm -f "$TRAY_PIDFILE"
|
|
fi
|
|
pgrep -f "chobit_tray\\.py" | while read -r cpid; do
|
|
kill "$cpid" 2>/dev/null
|
|
done || true
|
|
|
|
# Stop Godot
|
|
local stopped=0
|
|
if [ -f "$PIDFILE" ]; then
|
|
local pid
|
|
pid=$(cat "$PIDFILE" 2>/dev/null)
|
|
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
|
kill -- -"$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true
|
|
pkill -P "$pid" 2>/dev/null || true
|
|
wait "$pid" 2>/dev/null || true
|
|
echo "Stopped Godot (pid $pid)"
|
|
stopped=1
|
|
fi
|
|
rm -f "$PIDFILE"
|
|
fi
|
|
|
|
# Sweep stale Godot processes
|
|
local sweep_count=0
|
|
for cpid in $(pgrep -f "godot-bin.*(--path godot|@chobit/godot)" 2>/dev/null); do
|
|
kill "$cpid" 2>/dev/null && sweep_count=$((sweep_count + 1))
|
|
done
|
|
for cpid in $(pgrep -f "bwrap.*-- godot --path godot" 2>/dev/null); do
|
|
kill "$cpid" 2>/dev/null
|
|
done
|
|
|
|
if [ "$stopped" -eq 0 ] && [ "$sweep_count" -eq 0 ]; then
|
|
echo "Godot not running"
|
|
elif [ "$sweep_count" -gt 0 ]; then
|
|
echo "Swept $sweep_count stale Godot process(es)"
|
|
fi
|
|
|
|
# Stop bridge last — Godot may flush state on exit
|
|
if [ -f "$BRIDGE_PIDFILE" ]; then
|
|
local bridge_pid
|
|
bridge_pid=$(cat "$BRIDGE_PIDFILE" 2>/dev/null)
|
|
if [ -n "$bridge_pid" ] && kill -0 "$bridge_pid" 2>/dev/null; then
|
|
kill "$bridge_pid" 2>/dev/null && echo "Stopped bridge (pid $bridge_pid)" || true
|
|
fi
|
|
rm -f "$BRIDGE_PIDFILE"
|
|
fi
|
|
pgrep -f "chobit_bridge\\.py" | while read -r cpid; do
|
|
kill "$cpid" 2>/dev/null
|
|
done || true
|
|
}
|
|
|
|
cmd_restart() {
|
|
cmd_stop
|
|
sleep 2
|
|
cmd_start
|
|
}
|
|
|
|
cmd_verify() {
|
|
local failed=0
|
|
|
|
echo "=== Shared Source: Lint ==="
|
|
if (cd "$GODOT_DIR" && gdlint src/); then
|
|
echo "PASS"
|
|
else
|
|
echo "FAIL"
|
|
failed=1
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Desktop Platform: Lint ==="
|
|
if (cd "$GODOT_DIR" && gdlint platform/); then
|
|
echo "PASS"
|
|
else
|
|
echo "FAIL"
|
|
failed=1
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Shared Source: Format Check ==="
|
|
if (cd "$GODOT_DIR" && gdformat --check src/ 2>&1); then
|
|
echo "PASS"
|
|
else
|
|
echo "FAIL (run: cd godot-desktop && gdformat src/)"
|
|
failed=1
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Desktop Platform: Format Check ==="
|
|
if (cd "$GODOT_DIR" && gdformat --check platform/ 2>&1); then
|
|
echo "PASS"
|
|
else
|
|
echo "FAIL (run: cd godot-desktop && gdformat platform/)"
|
|
failed=1
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Godot Import ==="
|
|
local import_errors
|
|
import_errors=$($GODOT --headless --path "$GODOT_DIR" --import 2>&1 | grep -iE "error|fail" || true)
|
|
if [ -z "$import_errors" ]; then
|
|
echo "PASS"
|
|
else
|
|
echo "$import_errors"
|
|
echo "FAIL"
|
|
failed=1
|
|
fi
|
|
|
|
echo ""
|
|
if [ "$failed" -eq 0 ]; then
|
|
echo "All checks passed."
|
|
else
|
|
echo "Verification failed."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
cmd_editor() {
|
|
$GODOT --editor --path "$GODOT_DIR"
|
|
}
|
|
|
|
cmd_mobile_editor() {
|
|
$GODOT --editor --path "$ROOT/godot-mobile"
|
|
}
|
|
|
|
cmd_screenshot() {
|
|
$GODOT --path "$GODOT_DIR" --script tools/screenshot.gd 2>&1 | tail -1
|
|
}
|
|
|
|
case "${1:-}" in
|
|
""|start) cmd_start ;;
|
|
stop) cmd_stop ;;
|
|
restart) cmd_restart ;;
|
|
verify) cmd_verify ;;
|
|
editor) cmd_editor ;;
|
|
mobile-editor) cmd_mobile_editor ;;
|
|
screenshot) cmd_screenshot ;;
|
|
*)
|
|
echo "Usage: ./run [command]"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " (none), start Launch bridge + companion + tray (desktop)"
|
|
echo " stop Stop everything"
|
|
echo " restart Stop then start"
|
|
echo " verify Run lint, format check, and Godot import"
|
|
echo " editor Open Godot desktop editor"
|
|
echo " mobile-editor Open Godot mobile editor"
|
|
echo " screenshot Capture a screenshot"
|
|
exit 1
|
|
;;
|
|
esac
|