Skip to content

Commit

Permalink
refactor status bar state management
Browse files Browse the repository at this point in the history
  • Loading branch information
furudean committed Jul 13, 2024
1 parent 6de598b commit 85dcb27
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 130 deletions.
33 changes: 27 additions & 6 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ import { install_rpe, uninstall_rpes } from './lib/rpe'
import { launch_renpy } from './lib/launch'
import { get_config, set_config } from './lib/util'
import { resolve_path, path_exists, path_is_sdk } from './lib/path'
import { StatusBar } from './lib/status_bar'

const logger = get_logger()

let pm: ProcessManager
let follow_cursor: FollowCursor

export function activate(context: vscode.ExtensionContext) {
follow_cursor = new FollowCursor({ context })
pm = new ProcessManager({ follow_cursor })
follow_cursor.add_pm(pm)
const status_bar = new StatusBar({ context })
const follow_cursor = new FollowCursor({ context, status_bar })

pm = new ProcessManager({ status_bar })

context.subscriptions.push(
vscode.commands.registerCommand('renpyWarp.warpToLine', async () => {
Expand All @@ -29,6 +30,7 @@ export function activate(context: vscode.ExtensionContext) {
context,
pm,
follow_cursor,
status_bar,
})
} catch (error: any) {
logger.error(error)
Expand All @@ -50,6 +52,7 @@ export function activate(context: vscode.ExtensionContext) {
context,
pm,
follow_cursor,
status_bar,
})
} catch (error: any) {
logger.error(error)
Expand All @@ -59,7 +62,7 @@ export function activate(context: vscode.ExtensionContext) {

vscode.commands.registerCommand('renpyWarp.launch', async () => {
try {
await launch_renpy({ context, pm, follow_cursor })
await launch_renpy({ context, pm, follow_cursor, status_bar })
} catch (error: any) {
logger.error(error)
}
Expand All @@ -69,7 +72,25 @@ export function activate(context: vscode.ExtensionContext) {
if (follow_cursor.active) {
follow_cursor.disable()
} else {
follow_cursor.enable()
if (pm.length > 1) {
vscode.window.showErrorMessage(
"Can't follow cursor with multiple open processes",
'OK'
)
return
}

const process = pm.at(0)

if (process === undefined) {
vscode.window.showErrorMessage(
"Ren'Py not running. Cannot follow cursor.",
'OK'
)
return
}

follow_cursor.enable(process)
}
}),

Expand Down
70 changes: 21 additions & 49 deletions src/lib/follow_cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { get_logger } from './logger'
import path from 'upath'
import p_throttle from 'p-throttle'
import { find_game_root } from './sh'
import { StatusBar } from './status_bar'

const logger = get_logger()
const last_warps = new Map<number, string>()
Expand Down Expand Up @@ -96,48 +97,26 @@ const warp_renpy_to_cursor_throttled = throttle(warp_renpy_to_cursor)

export class FollowCursor {
private context: vscode.ExtensionContext
private pm: ProcessManager | undefined
private status_bar: StatusBar
private text_editor_handle: vscode.Disposable | undefined = undefined

status_bar: vscode.StatusBarItem
active: boolean = false

constructor({ context }: { context: vscode.ExtensionContext }) {
constructor({
context,
status_bar,
}: {
context: vscode.ExtensionContext
status_bar: StatusBar
}) {
this.context = context

this.status_bar = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
0
)

this.context.subscriptions.push(this.status_bar)
this.status_bar = status_bar

this.disable()
}

add_pm(pm: ProcessManager) {
this.pm = pm
}

async enable() {
if (!this.pm) throw new Error('no ProcessManager in FollowCursor')

if (this.pm.length > 1) {
vscode.window.showErrorMessage(
"Can't follow cursor with multiple open processes",
'OK'
)
}

const process = this.pm.at(0)

if (process === undefined) {
vscode.window.showErrorMessage(
"Ren'Py not running. Cannot follow cursor.",
'OK'
)
return
}
async enable(process: RenpyProcess) {
if (this.active) return

if (!get_config('renpyExtensionsEnabled')) {
vscode.window.showErrorMessage(
Expand All @@ -147,16 +126,6 @@ export class FollowCursor {
return
}

this.active = true

this.status_bar.text = '$(pinned) Following Cursor'
this.status_bar.color = new vscode.ThemeColor(
'statusBarItem.warningForeground'
)
this.status_bar.backgroundColor = new vscode.ThemeColor(
'statusBarItem.warningBackground'
)

this.text_editor_handle?.dispose()
this.text_editor_handle = vscode.window.onDidChangeTextEditorSelection(
async (event) => {
Expand All @@ -173,6 +142,11 @@ export class FollowCursor {
)
this.context.subscriptions.push(this.text_editor_handle)

this.active = true
this.status_bar.update(() => ({
is_follow_cursor: true,
}))

if (
["Visual Studio Code updates Ren'Py", 'Update both'].includes(
get_config('followCursorMode')
Expand All @@ -183,14 +157,12 @@ export class FollowCursor {
}

disable() {
if (!this.active) return
this.active = false

this.status_bar.text = '$(pin) Follow Cursor'
this.status_bar.command = 'renpyWarp.toggleFollowCursor'
this.status_bar.tooltip =
"When enabled, keep editor cursor and Ren'Py in sync"
this.status_bar.color = undefined
this.status_bar.backgroundColor = undefined
this.status_bar.update(() => ({
is_follow_cursor: false,
}))

this.text_editor_handle?.dispose()
this.text_editor_handle = undefined
Expand Down
28 changes: 18 additions & 10 deletions src/lib/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { get_logger } from './logger'
import { find_game_root, get_renpy_sh } from './sh'
import { has_any_rpe, has_current_rpe, install_rpe } from './rpe'
import { start_websocket_server, get_open_port } from './socket'
import { StatusBar } from './status_bar'

const logger = get_logger()

Expand All @@ -24,6 +25,7 @@ interface LaunchRenpyOptions {
context: vscode.ExtensionContext
pm: ProcessManager
follow_cursor: FollowCursor
status_bar: StatusBar
}

/**
Expand All @@ -42,6 +44,7 @@ export async function launch_renpy({
line,
context,
pm,
status_bar,
follow_cursor,
}: LaunchRenpyOptions): Promise<RenpyProcess | undefined> {
const is_development_mode =
Expand Down Expand Up @@ -114,8 +117,9 @@ export async function launch_renpy({
} else {
logger.info("opening new ren'py window")

const ref = pm.join()
pm.update_status_bar()
status_bar.update(({ starting_processes }) => ({
starting_processes: starting_processes + 1,
}))

try {
const socket_port = await get_open_port()
Expand Down Expand Up @@ -228,7 +232,7 @@ export async function launch_renpy({
pm.length === 1
) {
logger.info('enabling follow cursor on launch')
await follow_cursor.enable()
await follow_cursor.enable(rpp)
}

if (
Expand All @@ -243,10 +247,11 @@ export async function launch_renpy({
)
}

cancel.onCancellationRequested(() => {
const cancelation = cancel.onCancellationRequested(() => {
rpp?.kill()
pm.leave(ref)
pm.update_status_bar()
status_bar.update(({ starting_processes }) => ({
starting_processes: starting_processes - 1,
}))
})

if (extensions_enabled) {
Expand All @@ -262,17 +267,20 @@ export async function launch_renpy({
logger.debug('process connected to socket first time')
}

pm.leave(ref)
pm.update_status_bar()
status_bar.update(({ starting_processes }) => ({
starting_processes: starting_processes - 1,
}))
cancelation.dispose()

return rpp
}
)
} catch (e) {
throw e
} finally {
pm.leave(ref)
pm.update_status_bar()
status_bar.update(({ starting_processes }) => ({
starting_processes: starting_processes - 1,
}))
}
}
}
76 changes: 11 additions & 65 deletions src/lib/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { get_config } from './util'
import { get_logger } from './logger'
import pidtree from 'pidtree'
import { windowManager } from 'node-window-manager'
import { StatusBar } from './status_bar'

const logger = get_logger()

Expand Down Expand Up @@ -188,35 +189,29 @@ export class RenpyProcess {
}

export class ProcessManager {
private processes: Map<number, RenpyProcess>
instance_status_bar: vscode.StatusBarItem
follow_cursor: FollowCursor
joins = new Set<number>()
private processes = new Map<number, RenpyProcess>()
private status_bar: StatusBar

constructor({ follow_cursor }: { follow_cursor: FollowCursor }) {
constructor({ status_bar }: { status_bar: StatusBar }) {
this.processes = new Map()
this.follow_cursor = follow_cursor

this.instance_status_bar = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
0
)

this.update_status_bar()
this.status_bar = status_bar
}

/** @param {RenpyProcess} process */
async add(process: RenpyProcess) {
if (!process.process.pid) throw new Error('no pid in process')

this.processes.set(process.process.pid, process)
this.update_status_bar()

this.status_bar.update(({ running_processes }) => ({
running_processes: running_processes + 1,
}))
process.process.on('exit', (code) => {
if (!process.process.pid) throw new Error('no pid in process')

this.processes.delete(process.process.pid)
this.update_status_bar()
this.status_bar.update(({ running_processes }) => ({
running_processes: running_processes - 1,
}))

if (code) {
vscode.window
Expand Down Expand Up @@ -263,60 +258,11 @@ export class ProcessManager {
}
}

update_status_bar() {
this.instance_status_bar.show()

if (this.joins.size) {
this.instance_status_bar.text = `$(loading~spin) Starting Ren'Py...`
this.instance_status_bar.command = undefined
this.instance_status_bar.tooltip = undefined

this.follow_cursor.status_bar.hide()

return
}

if (this.length === 1 && get_config('renpyExtensionsEnabled')) {
this.follow_cursor.status_bar.show()
} else {
this.follow_cursor.status_bar.hide()
}

if (this.length) {
this.instance_status_bar.text = `$(debug-stop) Quit Ren'Py`
this.instance_status_bar.command = 'renpyWarp.killAll'
this.instance_status_bar.tooltip =
"Kill all running Ren'Py instances"
} else {
this.instance_status_bar.text = `$(play) Launch Project`
this.instance_status_bar.command = 'renpyWarp.launch'
this.instance_status_bar.tooltip = "Launch new Ren'Py instance"

if (this.follow_cursor.active) {
this.follow_cursor.disable()
}
}
}

get length() {
return this.processes.size
}

get pids(): number[] {
return [...this.processes.keys()]
}

join(): number {
const ref = Math.random()
logger.trace('join', ref)

this.joins.add(ref)

return ref
}

leave(ref: number): void {
this.joins.delete(ref)
logger.trace('leave', ref)
}
}
Loading

0 comments on commit 85dcb27

Please sign in to comment.