diff --git a/.github/workflows/build-tauri.yml b/.github/workflows/build-tauri.yml index aae840b..5c8f26d 100644 --- a/.github/workflows/build-tauri.yml +++ b/.github/workflows/build-tauri.yml @@ -33,8 +33,8 @@ jobs: APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} with: - tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version - releaseName: 'Saturn v__VERSION__' + tagName: app-v0.1.10l # the action automatically replaces \_\_VERSION\_\_ with the app version + releaseName: 'Saturn v0.1.10l' releaseBody: 'See attached builds.' releaseDraft: true prerelease: false diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index beb72a0..8fd001f 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3511,6 +3511,9 @@ dependencies = [ "tauri-build", "titan", "tokio", + "tracing", + "tracing-appender", + "tracing-subscriber", "uuid", ] @@ -4550,6 +4553,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.27" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f865262..3e642df 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -25,6 +25,9 @@ uuid = "1.5.0" notify = "6.1.1" base64 = "0.22.1" num = "0.4.1" +tracing = "0.1.40" +tracing-subscriber = "0.3.18" +tracing-appender = "0.2.3" saturn_backend = { path = "../src-backend" } titan = { git = "https://github.com/1whatleytay/titan.git", branch = "main" } diff --git a/src-tauri/src/access_manager.rs b/src-tauri/src/access_manager.rs index f772e46..4bc51b3 100644 --- a/src-tauri/src/access_manager.rs +++ b/src-tauri/src/access_manager.rs @@ -124,30 +124,48 @@ impl AccessManager { return }; + tracing::info!("FS event for {}: {:?}", path.to_string_lossy(), event); + match event.kind { notify::EventKind::Create(_) => { + tracing::info!("Emitting CREATE access_manager event for {}", path.to_string_lossy()); + app.emit_all("save:create", path).ok(); } notify::EventKind::Remove(_) => { + tracing::info!("Emitting REMOVE access_manager event for {}", path.to_string_lossy()); + app.emit_all("save:remove", path).ok(); } notify::EventKind::Modify(ModifyKind::Name(_)) => { if path.exists() { + tracing::info!("Emitting MODIFY + CREATE access_manager event for {}", path.to_string_lossy()); + app.emit_all("save:create", path).ok(); } else { + tracing::info!("Emitting MODIFY + REMOVE access_manager event for {}", path.to_string_lossy()); + app.emit_all("save:remove", path).ok(); } } notify::EventKind::Modify(ModifyKind::Data(_) | ModifyKind::Any) => { + tracing::info!("Emitting MODIFY + DATA access_manager event for {}", path.to_string_lossy()); + // If the path is in dismiss, we probably caused the save. if details.dismiss.remove(path) { + tracing::info!("Dismissed modify to {}", path.to_string_lossy()); + return } if let Ok(data) = fs::read_to_string(path) { + tracing::info!("Reading full data again from {} ({} bytes)", path.to_string_lossy(), data.len()); + app.emit_all("save:modify", AccessModify { path: path.to_string_lossy().to_string(), data: Text(data) }).ok(); + } else { + tracing::info!("Failed to read {}, skipping event", path.to_string_lossy()); } } _ => {} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index e32720d..9af4478 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -42,7 +42,26 @@ fn is_debug() -> bool { cfg!(debug_assertions) } +#[tauri::command] +fn send_trace(text: String) { + tracing::info!("(JS) {text}"); +} + fn main() { + let mut desktop = tauri::api::path::home_dir().unwrap(); + + desktop.push("Desktop/"); + + let appender = tracing_appender::rolling::daily(desktop.clone(), "saturn-log"); + let (writer, _guard) = tracing_appender::non_blocking(appender); + + tracing_subscriber::fmt() + .with_writer(writer) + .with_ansi(false) + .init(); + + tracing::info!("Logging initialized. Hello world!"); + let menu = create_menu(); tauri::Builder::default() @@ -58,6 +77,8 @@ fn main() { .on_window_event(|event| { match event.event() { FileDrop(FileDropEvent::Dropped(paths)) => { + tracing::info!("File drop."); + let app = event.window().app_handle(); let manager: tauri::State = app.state(); @@ -110,6 +131,7 @@ fn main() { export_hex_regions, export_hex_contents, export_binary_contents, + send_trace, ]) .register_uri_scheme_protocol("midi", midi_protocol) .register_uri_scheme_protocol("display", display_protocol) diff --git a/src/App.vue b/src/App.vue index 8a9b2f3..0601cba 100644 --- a/src/App.vue +++ b/src/App.vue @@ -6,4 +6,11 @@ diff --git a/src/main.ts b/src/main.ts index 18f2cfa..5d9221b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,6 +7,14 @@ import { setupEvents } from './utils/events' import { setupShortcuts } from './utils/platform-shortcuts' import { setupWindow } from './utils/window' import { setupBackend } from './state/backend' +import { invoke } from '@tauri-apps/api' + +invoke('send_trace', { text: 'wake' }) + .then(() => { }) + +window.addEventListener('error', async e => { + await invoke('send_trace', { text: `![JS ERROR]! ${e.message} - (${e.filename}, ${e.lineno}, ${e.colno}) - ${e.error}` }) +}) createApp(App).mount('#app') diff --git a/src/utils/cursor.ts b/src/utils/cursor.ts index 8d895c6..246468b 100644 --- a/src/utils/cursor.ts +++ b/src/utils/cursor.ts @@ -11,6 +11,7 @@ import { hasActionKey, hasAltKey } from './query/shortcut-key' import { selectionRange, CursorState } from './tabs' import { EditorSettings } from './settings' import { grabWhitespace } from './languages/language' +import { invoke } from '@tauri-apps/api' export interface CursorPosition { offsetX: number @@ -642,6 +643,9 @@ export function useCursor( const last = pressedBackspace pressedBackspace = false + invoke('send_trace', { text: `keydown ${event.key} s: ${event.shiftKey} m: ${hasActionKey(event)} a: ${event.altKey}` }) + .then(() => { }) + switch (event.key) { case 'ArrowLeft': if (hasActionKey(event)) { diff --git a/src/utils/debug.ts b/src/utils/debug.ts index 931cb3e..6327238 100644 --- a/src/utils/debug.ts +++ b/src/utils/debug.ts @@ -17,6 +17,7 @@ import { tab, settings } from '../state/state' import { format } from 'date-fns' import { PromptType, saveCurrentTab } from './events' import { computed, toRaw } from 'vue' +import { invoke } from '@tauri-apps/api' export async function setBreakpoint(line: number, remove: boolean) { const currentTab = tab() @@ -178,6 +179,8 @@ export async function resume() { return } + await invoke('send_trace', { text: 'resuming' }) + clearDebug() const current = tab() @@ -195,12 +198,15 @@ export async function resume() { await saveCurrentTab(PromptType.NeverPrompt) consoleData.execution = await backend.createExecution(text, path, settings.execution.timeTravel, current.profile) + + await invoke('send_trace', { text: 'created execution' }) } consoleData.showConsole = true consoleData.mode = ExecutionModeType.Running const assemblerResult = await consoleData.execution.configure() + await invoke('send_trace', { text: `configured asm result ${JSON.stringify(assemblerResult)}` }) if (assemblerResult) { postBuildMessage(assemblerResult) @@ -217,6 +223,8 @@ export async function resume() { toRaw(usedBreakpoints) ) + await invoke('send_trace', { text: `resume finished ${JSON.stringify(result)}` }) + if (result) { await postDebugInformationWithPcHint(result) } else { diff --git a/src/utils/editor.ts b/src/utils/editor.ts index 7655773..c720345 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -5,6 +5,7 @@ import { } from './query/alt-consume' import { grabWhitespace } from './languages/language' import { splitLines } from './split-lines' +import { invoke } from '@tauri-apps/api' export interface SelectionIndex { line: number @@ -176,7 +177,9 @@ export class Editor { this.redoOperations = [] - console.log('try again') + invoke('send_trace', { text: `mutate: @${line} -${count} +${insert} - ${this.lineCount()}` }) + .then(() => { }) + this.onDirty(line, count, this.data.slice(line, line + insert)) } @@ -246,6 +249,7 @@ export class Editor { drop(range: SelectionRange, inclusive: boolean = false) { if (range.startLine == range.endLine) { if (inclusive) { + invoke('send_trace', { text: `editor DROPLINEi: ${JSON.stringify(range)}` }).then(() => {}) this.mutate(range.startLine, 1, 0, () => { this.data.splice(range.startLine, 1) }) @@ -255,6 +259,8 @@ export class Editor { const leading = text.substring(0, range.startIndex) const trailing = text.substring(range.endIndex) + invoke('send_trace', { text: `editor DROPLINE: ${JSON.stringify(range)}` }).then(() => {}) + this.mutateLine(range.startLine, () => { this.data[range.startLine] = leading + trailing }) @@ -263,6 +269,8 @@ export class Editor { const leading = this.data[range.startLine].substring(0, range.startIndex) const trailing = this.data[range.endLine].substring(range.endIndex) + invoke('send_trace', { text: `editor DROP: ${JSON.stringify(range)} ${inclusive}` }).then(() => {}) + this.mutate( range.startLine, range.endLine - range.startLine + 1, @@ -287,6 +295,8 @@ export class Editor { ) { const count = end - start + 1 + invoke('send_trace', { text: `editor PREFIX: ${start} ${end} ${character} ${whitespace}` }).then(() => {}) + this.mutate(start, count, count, () => { for (let a = start; a <= end; a++) { if (whitespace) { @@ -305,6 +315,8 @@ export class Editor { } crop(start: number, ranges: (LineRange | null)[]) { + invoke('send_trace', { text: `editor CROP: ${start} ${ranges} (${ranges.length})` }).then(() => {}) + this.mutate(start, ranges.length, ranges.length, () => { ranges.forEach((range, index) => { if (!range) { @@ -325,6 +337,8 @@ export class Editor { const leading = line.substring(0, index.index) const trailing = line.substring(index.index) + invoke('send_trace', { text: `editor PUT: ${JSON.stringify(index)} ${character}` }).then(() => {}) + // Mutate this.mutateLine(index.line, () => { this.data[index.line] = leading + character + trailing @@ -355,6 +369,8 @@ export class Editor { const last = rest[rest.length - 1].length rest[rest.length - 1] += trailing + invoke('send_trace', { text: `editor PASTE: ${JSON.stringify(index)} ${text}` }).then(() => {}) + // Mutate this.mutate(index.line, 1, textLines.length, () => { this.data[index.line] = leading + first @@ -368,7 +384,11 @@ export class Editor { const regex = new RegExp(`^( {1,${spacing}}|\\t)`, 'g') const match = this.data[line].match(regex) + invoke('send_trace', { text: `editor DROPTAB: ${line} ${spacing}` }).then(() => {}) + if (match && match.length) { + invoke('send_trace', { text: `editor DROPTAB done` }).then(() => {}) + const text = match[0] this.mutateLine(line, () => { @@ -396,6 +416,8 @@ export class Editor { ? trailing.substring(endMatch[0].length) : trailing + invoke('send_trace', { text: `editor NEWLINE: ${JSON.stringify(index)}` }).then(() => {}) + // Mutate this.mutate(index.line, 1, 2, () => { this.data[index.line] = leading @@ -405,14 +427,6 @@ export class Editor { return { line: index.line + 1, index: spacing.length } } - dropLines( - index: SelectionIndex - ) { - this.mutate(index.line, 1, 0, () => { - this.data.splice(index.line, 1) - }) - } - backspace( index: SelectionIndex, alt: boolean = false, @@ -428,6 +442,8 @@ export class Editor { const leading = line.substring(0, index.index - consumption) const trailing = line.substring(index.index) + invoke('send_trace', { text: `editor BACKSPACEi: ${JSON.stringify(index)} ${alt} ${space}` }).then(() => {}) + // Mutate this.mutateLine(index.line, () => { this.data[index.line] = leading + trailing @@ -438,6 +454,8 @@ export class Editor { const leading = this.data[index.line - 1] const trailing = this.data[index.line] + invoke('send_trace', { text: `editor BACKSPACE: ${JSON.stringify(index)} ${alt} ${space}` }).then(() => {}) + this.mutate(index.line - 1, 2, 1, () => { this.data[index.line - 1] = leading + trailing this.data.splice(index.line, 1) @@ -458,6 +476,8 @@ export class Editor { const leading = line.substring(0, index.index) const trailing = line.substring(index.index + consumption) + invoke('send_trace', { text: `editor DELFORWARDSi: ${JSON.stringify(index)} ${alt}` }).then(() => {}) + // Mutate this.mutateLine(index.line, () => { this.data[index.line] = leading + trailing @@ -468,6 +488,8 @@ export class Editor { const leading = this.data[index.line] const trailing = this.data[index.line + 1] + invoke('send_trace', { text: `editor DELFORWARDS: ${JSON.stringify(index)} ${alt}` }).then(() => {}) + this.mutate(index.line, 2, 1, () => { this.data[index.line] = leading + trailing this.data.splice(index.line + 1, 1) @@ -498,6 +520,8 @@ export class Editor { replaceAll(text: string) { const textLines = splitLines(text) + invoke('send_trace', { text: `editor REPLACEALL: ${text} (${text.length})` }).then(() => {}) + this.mutate(0, this.data.length, textLines.length, () => { this.data.splice(0, Infinity, ...textLines) }) diff --git a/src/utils/events.ts b/src/utils/events.ts index c5c4db4..3de7547 100644 --- a/src/utils/events.ts +++ b/src/utils/events.ts @@ -32,6 +32,7 @@ import { watch } from 'vue' import { MidiNote, playNote } from './midi' import { splitLines } from './split-lines' import { exportBinaryContents } from './query/serialize-files' +import { invoke } from '@tauri-apps/api' export enum PromptType { NeverPrompt, @@ -104,6 +105,9 @@ export async function saveCurrentTab( const current = tab() if (current) { + invoke('send_trace', { text: `saving current tab ${prompt}` }) + .then(() => { }) + await saveTab(current, prompt) } } @@ -283,6 +287,8 @@ export async function setupEvents() { }) await listen('save:modify', (event) => { + invoke('send_trace', { text: `got save:modify event` }).then(() => {}) + const modification = event.payload as { path: string, data: any @@ -294,6 +300,8 @@ export async function setupEvents() { for (const tab of tabsState.tabs) { if (tab.path === modification.path) { + invoke('send_trace', { text: `CALLING REPLACE ALL: ${modification} ${modification.path} ${modification.data.length}` }).then(() => {}) + editor.value.replaceAll(modification.data) tab.marked = false } diff --git a/src/utils/storage.ts b/src/utils/storage.ts index bf5858f..1aaf1c8 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -6,6 +6,7 @@ import { MipsHighlighter } from './languages/mips/language' import { HighlightsInterface } from './highlights' import { SuggestionsStorage } from './languages/suggestions' import { backend } from '../state/backend' +import { invoke } from '@tauri-apps/api' export interface StorageState { // editor: Editor @@ -129,6 +130,9 @@ export function useStorage( function createEditor(): Editor { const current = tab() + invoke('send_trace', { text: `computing editor for tab ${current?.title} and line count ${current?.lines.length}` }) + .then(() => { }) + return new Editor( current?.lines ?? ['Nothing yet.'], current?.cursor ?? { line: 0, index: 0 }, diff --git a/src/utils/tabs.ts b/src/utils/tabs.ts index 4c6e905..7b7ce34 100644 --- a/src/utils/tabs.ts +++ b/src/utils/tabs.ts @@ -13,6 +13,7 @@ import { closeWindow } from './window' import { splitLines } from './split-lines' import { accessReadText, accessSync } from './query/access-manager' import { backend } from '../state/backend' +import { invoke } from '@tauri-apps/api' export type CursorState = SelectionIndex & { highlight: SelectionIndex | null @@ -199,7 +200,7 @@ export function useTabs(): TabsResult { const values = localStorage.getItem(backupNameKey) if (values) { - const list = JSON.stringify(values) + const list = JSON.parse(values) for (const item of list) { localStorage.removeItem(item) @@ -214,6 +215,9 @@ export function useTabs(): TabsResult { localStorage.setItem(backupNameKey, JSON.stringify(result)) for (const [key, value] of map.entries()) { + invoke('send_trace', { text: `backing up ${key} ${value.length}` }) + .then(() => { }) + localStorage.setItem(backupKey(key), value) } } @@ -251,7 +255,12 @@ export function useTabs(): TabsResult { updateBackups(map) - localStorage.setItem(restoreKey, JSON.stringify(state)) + const restoreState = JSON.stringify(state) + + invoke('send_trace', { text: `BACKUP restore state: ${restoreState}` }) + .then(() => { }) + + localStorage.setItem(restoreKey, restoreState) } restore().then(() => {})