SNAPKITTYWEST's picture
push from SNAPKITTYWEST/sovereign-ide
ffc07fb verified
Raw History Blame Contribute Delete
7.35 kB
! Layer 15 β€” Sovereign IDE Application Shell
! Session state, workspace, main event loop, BOB context slot
! Maps to: bob-ide, bob-orchestrator
MODULE sovereign_shell
USE iso_c_binding
USE sovereign_runtime, ONLY: runtime_init, runtime_teardown, runtime_panic, str_intern
IMPLICIT NONE
PRIVATE
! ── Workspace descriptor ─────────────────────────────────────────────────
INTEGER, PARAMETER :: MAX_OPEN_FILES = 512
INTEGER, PARAMETER :: MAX_PANELS = 16
TYPE :: panel_t
REAL :: x = 0.0, y = 0.0, w = 1.0, h = 1.0
INTEGER :: buffer_idx = 0
LOGICAL :: active = .FALSE.
END TYPE panel_t
TYPE :: workspace_t
INTEGER(C_INT32_T) :: root_path_id = 0
INTEGER(C_INT32_T) :: open_files(MAX_OPEN_FILES)
INTEGER :: open_count = 0
TYPE(panel_t) :: panels(MAX_PANELS)
INTEGER :: panel_count = 1
INTEGER :: active_panel = 1
LOGICAL :: dirty = .FALSE.
END TYPE workspace_t
! ── Session state (WORM-sealed) ──────────────────────────────────────────
TYPE :: session_t
TYPE(workspace_t) :: workspace
INTEGER(C_INT64_T) :: frame_count = 0
LOGICAL :: bob_context_loaded = .FALSE.
INTEGER(C_INT32_T) :: session_id = 0
LOGICAL :: running = .FALSE.
END TYPE session_t
TYPE(session_t), SAVE :: g_session
PUBLIC :: shell_init
PUBLIC :: shell_run
PUBLIC :: shell_shutdown
PUBLIC :: shell_open_file
PUBLIC :: shell_close_file
PUBLIC :: shell_split_panel
PUBLIC :: shell_save_session
PUBLIC :: shell_restore_session
CONTAINS
! ---------------------------------------------------------------------------
SUBROUTINE shell_init(workspace_root)
CHARACTER(LEN=*), INTENT(IN) :: workspace_root
CALL runtime_init()
g_session%workspace%root_path_id = str_intern(workspace_root)
g_session%workspace%panel_count = 1
g_session%workspace%active_panel = 1
g_session%workspace%panels(1)%active = .TRUE.
g_session%running = .TRUE.
g_session%frame_count = 0
WRITE(*,'(A,A)') '[shell] init workspace: ', TRIM(workspace_root)
END SUBROUTINE shell_init
! ---------------------------------------------------------------------------
! Main event loop: poll β†’ update β†’ render β†’ repeat
SUBROUTINE shell_run()
DO WHILE (g_session%running)
g_session%frame_count = g_session%frame_count + 1
! 1. Poll OS events (Layer 1 platform)
! TODO: CALL platform_poll_events()
! 2. Process input (Layer 2 GUI input dispatch)
! TODO: CALL gui_process_input()
! 3. Update all active layers
! TODO: CALL lsp_tick() β€” Layer 12
! TODO: CALL dap_tick() β€” Layer 13
! TODO: CALL ext_host_tick() β€” Layer 14
! 4. Begin frame (Layer 2 GUI)
! TODO: CALL gui_begin_frame()
! 5. Render panels β†’ text buffers β†’ syntax highlighting
! TODO: CALL gui_render_panels()
! 6. End frame
! TODO: CALL gui_end_frame()
! 7. Auto-save session every 300 frames
IF (MOD(g_session%frame_count, 300) == 0) CALL shell_save_session()
! Stub: exit after first frame for now
g_session%running = .FALSE.
END DO
END SUBROUTINE shell_run
! ---------------------------------------------------------------------------
SUBROUTINE shell_shutdown()
CALL shell_save_session()
! Teardown in reverse order: 15 β†’ 0
! TODO: CALL ext_host_shutdown() β€” Layer 14
! TODO: CALL dap_shutdown() β€” Layer 13
! TODO: CALL lsp_shutdown() β€” Layer 12
! TODO: CALL build_shutdown() β€” Layer 11
! ...
CALL runtime_teardown()
WRITE(*,'(A,I0,A)') '[shell] shutdown after ', g_session%frame_count, ' frames'
END SUBROUTINE shell_shutdown
! ---------------------------------------------------------------------------
SUBROUTINE shell_open_file(path)
CHARACTER(LEN=*), INTENT(IN) :: path
INTEGER(C_INT32_T) :: fid
IF (g_session%workspace%open_count >= MAX_OPEN_FILES) &
CALL runtime_panic('shell_open_file: too many open files')
fid = str_intern(path)
g_session%workspace%open_count = g_session%workspace%open_count + 1
g_session%workspace%open_files(g_session%workspace%open_count) = fid
g_session%workspace%dirty = .TRUE.
WRITE(*,'(A,A)') '[shell] opened: ', TRIM(path)
END SUBROUTINE shell_open_file
! ---------------------------------------------------------------------------
SUBROUTINE shell_close_file(idx)
INTEGER, INTENT(IN) :: idx
INTEGER :: i
IF (idx < 1 .OR. idx > g_session%workspace%open_count) RETURN
DO i = idx, g_session%workspace%open_count - 1
g_session%workspace%open_files(i) = g_session%workspace%open_files(i+1)
END DO
g_session%workspace%open_count = g_session%workspace%open_count - 1
g_session%workspace%dirty = .TRUE.
END SUBROUTINE shell_close_file
! ---------------------------------------------------------------------------
SUBROUTINE shell_split_panel(direction)
CHARACTER(LEN=*), INTENT(IN) :: direction
INTEGER :: n
n = g_session%workspace%panel_count
IF (n >= MAX_PANELS) RETURN
g_session%workspace%panel_count = n + 1
g_session%workspace%panels(n+1)%active = .TRUE.
IF (direction == 'v') THEN
g_session%workspace%panels(n)%w = g_session%workspace%panels(n)%w * 0.5
g_session%workspace%panels(n+1)%x = g_session%workspace%panels(n)%x + g_session%workspace%panels(n)%w
g_session%workspace%panels(n+1)%w = g_session%workspace%panels(n)%w
ELSE
g_session%workspace%panels(n)%h = g_session%workspace%panels(n)%h * 0.5
g_session%workspace%panels(n+1)%y = g_session%workspace%panels(n)%y + g_session%workspace%panels(n)%h
g_session%workspace%panels(n+1)%h = g_session%workspace%panels(n)%h
END IF
g_session%workspace%dirty = .TRUE.
END SUBROUTINE shell_split_panel
! ---------------------------------------------------------------------------
! Session save: serialize workspace to WORM-sealed JSON
SUBROUTINE shell_save_session()
IF (.NOT. g_session%workspace%dirty) RETURN
! TODO: serialize workspace_t β†’ JSON
! TODO: CALL bifrost_worm_append(session_json) β€” Layer 0 WORM
g_session%workspace%dirty = .FALSE.
WRITE(*,'(A,I0)') '[shell] session saved at frame ', g_session%frame_count
END SUBROUTINE shell_save_session
! ---------------------------------------------------------------------------
SUBROUTINE shell_restore_session(session_path)
CHARACTER(LEN=*), INTENT(IN) :: session_path
! TODO: read WORM-sealed session file
! TODO: deserialize β†’ workspace_t
! TODO: re-open all files (Layer 3 buffer restore)
! TODO: reconnect BOB context (Layer 14 ext_host_connect_bob)
g_session%bob_context_loaded = .TRUE.
WRITE(*,'(A,A)') '[shell] restored session: ', TRIM(session_path)
END SUBROUTINE shell_restore_session
END MODULE sovereign_shell