1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-06-29 11:40:38 +00:00

Avoid excessive disk access while typing

- No longer constantly (over)writes files in the `internal\temp` folder while typing in the IDE, as the generated C/C++ code is buffered internally now.
- Buffers are automatically written out to disk on a `Make` request (F5/F11).
This commit is contained in:
Roland Heyder 2022-08-25 01:14:29 +02:00
parent 2de5fc24e0
commit 51667125c9
6 changed files with 1493 additions and 1292 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
This is a massively reduced version of "The Simplebuffer System" library
by RhoSigma. The full package with many more functions for bookmarking,
searching, copy'n'paste and EOL conversion, inclusive documentation and
examples can be downloaded from the respective forum post here:
https://qb64phoenix.com/forum/showthread.php?tid=486
Note: The sb_qb64_extension.bi/.bm files are not part of the buffer system.
These files provide glue code for use of the system inside qb64pe.

View file

@ -0,0 +1,7 @@
'--- This array holds the file names for the used buffers, the array is
'--- directly indexed using the buffer handles. This array is comparable
'--- to the "table of contents" of the harddrive.
'--- Avoid direct access, use the provided SUBs and FUNCTIONs.
'-----
REDIM SHARED SBufN(0 TO 99) AS STRING 'init for 100 buffers

View file

@ -0,0 +1,97 @@
'--- This function simulates the open behavior of real files depending
'--- on the file OPEN mode. That way the file OPEN calls are easily
'--- replaceable by OpenBuffer%() calls without worry about the internal
'--- differences of the buffer system compared to real files.
'--- Respective CLOSE calls can be simply removed as buffers remain
'--- always accessible until cleared/disposed.
'-----
'--- The file names given to this function should be just the same as
'--- you would use to open a real file, i.e. inclusive full or relative
'--- path as required.
'--- Modes names can be short, only the first character is checked.
'---------------------------------------------------------------------
FUNCTION OpenBuffer% (sbMode$, sbName$)
'--- option _explicit requirements ---
DIM buf%, nul&
'--- buffer already existing? ---
FOR buf% = 0 TO UBOUND(SBufN)
IF SBufN(buf%) = sbName$ THEN EXIT FOR
NEXT buf%
'--- simulate file modes ---
SELECT CASE UCASE$(LEFT$(sbMode$, 1))
CASE "A" 'append
IF buf% > UBOUND(SBufN) THEN GOSUB newBuf
nul& = SeekBuf&(buf%, 0, SBM_BufEnd)
CASE "B" 'binary
IF buf% > UBOUND(SBufN) THEN GOSUB newBuf
nul& = SeekBuf&(buf%, 0, SBM_BufStart)
CASE "I" 'input
IF buf% > UBOUND(SBufN) THEN ERROR 53 'buffer not found
nul& = SeekBuf&(buf%, 0, SBM_BufStart)
CASE "O" 'output
IF buf% <= UBOUND(SBufN) THEN DisposeBuf buf%: SBufN(buf%) = ""
GOSUB newBuf
CASE ELSE 'random or unknown mode
buf% = SBE_NoMoreBuffers 'not supported
END SELECT
OpenBuffer% = buf%
EXIT FUNCTION
'----------
newBuf:
buf% = CreateBuf%
IF buf% > UBOUND(SBufN) THEN REDIM _PRESERVE SBufN(0 TO buf% + 99) AS STRING 'extend by 100 buffers
SBufN(buf%) = sbName$
RETURN
END FUNCTION
'--- This subroutine will clear the given buffer or ALL buffers, if the
'--- name argument is empty.
'--- Clearing a buffer is the equivalent to KILLing a real file.
'-----
'--- To designate a single buffer to clear, use the same file name as
'--- given at the respective OpenBuffer%() call.
'---------------------------------------------------------------------
SUB ClearBuffers (sbName$)
'--- option _explicit requirements ---
DIM buf%
'--- clear/dispose buffer(s) ---
IF sbName$ <> "" THEN
FOR buf% = 0 TO UBOUND(SBufN)
IF SBufN(buf%) = sbName$ THEN EXIT FOR 'buffer found
NEXT buf%
IF buf% > UBOUND(SBufN) THEN EXIT SUB 'buffer doesn't exist
DisposeBuf buf%: SBufN(buf%) = ""
ELSE
FOR buf% = 0 TO UBOUND(SBufN)
IF SBufN(buf%) <> "" THEN DisposeBuf buf%: SBufN(buf%) = ""
NEXT buf%
END IF
END SUB
'--- This subroutine will write the current contents of the given buffer
'--- or ALL buffers, if the name argument is empty, into the respective
'--- files on disk (using names as given by the OpenBuffer%() function)
'--- The change state of the buffer(s) is checked first to avoid needless
'--- disk writes.
'-----
'--- To designate a single buffer to write, use the same file name as
'--- given at the respective OpenBuffer%() call.
'---------------------------------------------------------------------
SUB WriteBuffers (sbName$)
'--- option _explicit requirements ---
DIM buf%
'--- write buffer(s) ---
IF sbName$ <> "" THEN
FOR buf% = 0 TO UBOUND(SBufN)
IF SBufN(buf%) = sbName$ THEN EXIT FOR 'buffer found
NEXT buf%
IF buf% > UBOUND(SBufN) THEN EXIT SUB 'buffer doesn't exist
IF IsBufChanged%(buf%) THEN BufToFile buf%, SBufN(buf%)
ELSE
FOR buf% = 0 TO UBOUND(SBufN)
IF SBufN(buf%) <> "" THEN
IF IsBufChanged%(buf%) THEN BufToFile buf%, SBufN(buf%)
END IF
NEXT buf%
END IF
END SUB

View file

@ -0,0 +1,32 @@
'+---------------+---------------------------------------------------+
'| ###### ###### | .--. . .-. |
'| ## ## ## # | | )| ( ) o |
'| ## ## ## | |--' |--. .-. `-. . .-...--.--. .-. |
'| ###### ## | | \ | |( )( ) | ( || | |( ) |
'| ## ## | ' `' `-`-' `-'-' `-`-`|' ' `-`-'`- |
'| ## ## # | ._.' |
'| ## ###### | Sources & Documents placed in the Public Domain. |
'+---------------+---------------------------------------------------+
'--- The internal array for data storage
'-----
'never access this directly, use functions in simplebuffer.bm
REDIM SHARED simplebuffer_array$(0 TO 10599) 'init for 100 buffers
'--- Simplebuffer Errors (most FUNCTIONs)
'-----
'initializer error returns
CONST SBE_NoMoreBuffers = -1
'operational error returns
CONST SBE_UnknownMode = -11
CONST SBE_OutOfBounds = -12
'--- Simplebuffer Modes (SeekBuf) ---
'-----
'use for mode% argument
CONST SBM_BufStart = -22
CONST SBM_BufCurrent = -23
CONST SBM_BufEnd = -24
'$INCLUDE: 'sb_qb64pe_extension.bi'

View file

@ -0,0 +1,184 @@
'+---------------+---------------------------------------------------+
'| ###### ###### | .--. . .-. |
'| ## ## ## # | | )| ( ) o |
'| ## ## ## | |--' |--. .-. `-. . .-...--.--. .-. |
'| ###### ## | | \ | |( )( ) | ( || | |( ) |
'| ## ## | ' `' `-`-' `-'-' `-`-`|' ' `-`-'`- |
'| ## ## # | ._.' |
'| ## ###### | Sources & Documents placed in the Public Domain. |
'+---------------+---------------------------------------------------+
'---------------------------------------------------------------------
FUNCTION CreateBuf%
'--- option _explicit requirements ---
DIM aub&, buf&
'--- find next free handle ---
aub& = UBOUND(simplebuffer_array$)
buf& = 0: CreateBuf% = SBE_NoMoreBuffers
WHILE buf& < aub&
IF simplebuffer_array$(buf& + 1) = "" THEN EXIT WHILE
buf& = buf& + 106
IF buf& >= 3473408 THEN EXIT FUNCTION '=> allow max. 32768 buffers
WEND
'--- expand array, if necessary ---
IF aub& < buf& + 105 THEN REDIM _PRESERVE simplebuffer_array$(0 TO buf& + 10599) 'extend by 100 buffers
'--- init buffer ---
simplebuffer_array$(buf& + 0) = SPACE$(10000) ' => the actual buffer
simplebuffer_array$(buf& + 1) = MKL$(1) + MKL$(0) + "EolU" + MKL$(-1) '=> cursor position + buffer length + EOL mode + changed state
'--- return new handle ---
CreateBuf% = buf& \ 106
END FUNCTION
'---------------------------------------------------------------------
SUB DisposeBuf (handle%)
'--- option _explicit requirements ---
DIM buf&
'--- erase buffer data ---
buf& = handle% * 106
simplebuffer_array$(buf& + 0) = ""
simplebuffer_array$(buf& + 1) = ""
END SUB
'---------------------------------------------------------------------
SUB BufToFile (handle%, fileSpec$)
'--- option _explicit requirements ---
DIM buf&, ff%, op$
'--- write file (overwrite existing !!!) ---
buf& = handle% * 106
ff% = FREEFILE: op$ = LEFT$(simplebuffer_array$(buf& + 0), GetBufLen&(handle%))
OPEN fileSpec$ FOR OUTPUT LOCK WRITE AS ff%: CLOSE ff%
OPEN fileSpec$ FOR BINARY LOCK WRITE AS ff%
PUT ff%, , op$
CLOSE ff%
'--- set state ---
MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(0)
END SUB
'---------------------------------------------------------------------
SUB WriteBufLine (handle%, text$)
'--- option _explicit requirements ---
DIM buf&, cur&, txl&, brc$, brl%, cbl&&, chg&
'--- prepare values ---
buf& = handle% * 106
cur& = GetBufPos&(handle%): txl& = LEN(text$)
brc$ = BufEolSeq$(handle%): brl% = LEN(brc$)
cbl&& = GetBufLen&(handle%): chg& = txl& + brl%
'--- check buffer length ---
IF cbl&& + chg& > LEN(simplebuffer_array$(buf& + 0)) THEN
simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(10000)
END IF
'--- write into buffer ---
MID$(simplebuffer_array$(buf& + 0), cur&) = text$ + brc$ + MID$(simplebuffer_array$(buf& + 0), cur&, cbl&& - cur& + 1)
MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + chg&)
MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& + chg&)
MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1)
END SUB
'---------------------------------------------------------------------
FUNCTION ReadBufRawData$ (handle%, size&) 'size change intended
'--- option _explicit requirements ---
DIM buf&, cur&, eob&
'--- prepare values ---
buf& = handle% * 106
cur& = GetBufPos&(handle%): eob& = GetBufLen&(handle%) + 1
IF size& > eob& - cur& THEN size& = eob& - cur&
'--- read from buffer ---
ReadBufRawData$ = MID$(simplebuffer_array$(buf& + 0), cur&, size&)
MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + size&)
END FUNCTION
'---------------------------------------------------------------------
SUB WriteBufRawData (handle%, rawData$)
'--- option _explicit requirements ---
DIM buf&, cur&, rdl&, cbl&&
'--- prepare values ---
buf& = handle% * 106
cur& = GetBufPos&(handle%): rdl& = LEN(rawData$)
cbl&& = GetBufLen&(handle%)
'--- check buffer length ---
IF cbl&& + rdl& > LEN(simplebuffer_array$(buf& + 0)) THEN
simplebuffer_array$(buf& + 0) = simplebuffer_array$(buf& + 0) + SPACE$(10000)
END IF
'--- write into buffer ---
MID$(simplebuffer_array$(buf& + 0), cur&) = rawData$ + MID$(simplebuffer_array$(buf& + 0), cur&, cbl&& - cur& + 1)
MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(cur& + rdl&)
MID$(simplebuffer_array$(buf& + 1), 5, 4) = MKL$(cbl&& + rdl&)
IF rdl& > 0 THEN
MID$(simplebuffer_array$(buf& + 1), 9, 4) = "EolU"
MID$(simplebuffer_array$(buf& + 1), 13, 4) = MKL$(-1)
END IF
END SUB
'---------------------------------------------------------------------
FUNCTION SeekBuf& (handle%, displace&, mode%)
'--- option _explicit requirements ---
DIM buf&, cur&, eob&, brc$, brl%, origin&, newPos&
'--- prepare values ---
buf& = handle% * 106
cur& = GetBufPos&(handle%): eob& = GetBufLen&(handle%) + 1
brc$ = BufEolSeq$(handle%): brl% = LEN(brc$)
'--- select origin ---
SELECT CASE mode%
CASE SBM_BufStart: origin& = 1
CASE SBM_BufCurrent: origin& = cur&
CASE SBM_BufEnd: origin& = eob&
CASE ELSE
SeekBuf& = SBE_UnknownMode
EXIT FUNCTION
END SELECT
'--- seek to new position ---
newPos& = origin& + displace&
IF newPos& < 1 OR newPos& > eob& THEN
SeekBuf& = SBE_OutOfBounds
ELSE
MID$(simplebuffer_array$(buf& + 1), 1, 4) = MKL$(newPos&)
SeekBuf& = cur&
END IF
END FUNCTION
'---------------------------------------------------------------------
FUNCTION GetBufPos& (handle%)
'--- option _explicit requirements ---
DIM buf&
'--- return cursor position in buffer ---
buf& = handle% * 106
GetBufPos& = CVL(MID$(simplebuffer_array$(buf& + 1), 1, 4))
END FUNCTION
'---------------------------------------------------------------------
FUNCTION GetBufLen& (handle%)
'--- option _explicit requirements ---
DIM buf&
'--- return actual buffer length ---
buf& = handle% * 106
GetBufLen& = CVL(MID$(simplebuffer_array$(buf& + 1), 5, 4))
END FUNCTION
'---------------------------------------------------------------------
FUNCTION IsBufChanged% (handle%)
'--- option _explicit requirements ---
DIM buf&
'--- return BufChanged condition ---
buf& = handle% * 106
IsBufChanged% = CVL(MID$(simplebuffer_array$(buf& + 1), 13, 4))
END FUNCTION
'---------------------------------------------------------------------
FUNCTION BufEolSeq$ (handle%)
'--- option _explicit requirements ---
DIM buf&
'--- return buffer specific EndOfLine sequence ---
buf& = handle% * 106
SELECT CASE MID$(simplebuffer_array$(buf& + 1), 9, 4)
CASE "EolU", "EolN" 'OS native mode
BufEolSeq$ = CHR$(13) + CHR$(10) 'default is Windows
IF INSTR(_OS$, "[LINUX]") > 0 THEN BufEolSeq$ = CHR$(10) 'true for MacOSX too
CASE "EolL" 'forced Linux/MacOSX
BufEolSeq$ = CHR$(10)
CASE "EolW" 'forced Windows
BufEolSeq$ = CHR$(13) + CHR$(10)
END SELECT
END FUNCTION
'$INCLUDE: 'sb_qb64pe_extension.bm'