(10-13-2023, 08:06 AM)SMcNeill Wrote: @RhoSigma Aye, I remember all those rules which we came up with, and like you, I try to always build my libraries up to those standards. The thing is, as time passes -- that discussion was about 5 years ago -- you sometimes pick up new tricks on how to do things. Let me showcase a few new tricks that I've started to add to my habits for library creation:
Code: (Select All)$IF INCLUDE_ALL = TRUE OR INCLUDE_SCREEN = TRUE OR INCLUDE_SCROLLDOWN = TRUE THEN
$IF SCROLLDOWN_BM = UNDEFINED THEN
$LET SCROLLDOWN_BM = TRUE
SUB ScrollDown (ImageHandle AS LONG)
$CHECKING:OFF
DIM m AS _MEM
DIM AS LONG p, w
DIM AS STRING t
m = _MEMIMAGE(ImageHandle)
p = _PIXELSIZE
IF p = 0 THEN w = _WIDTH * 2 ELSE w = _FONTHEIGHT * _WIDTH * p
t$ = SPACE$(m.SIZE - w)
_MEMGET m, m.OFFSET, t$
CLS
_MEMPUT m, m.OFFSET + w, t$
_MEMFREE m
$CHECKING:ON
END SUB
$END IF
$END IF
$IF INCLUDE_ALL = TRUE OR INCLUDE_SOUND = TRUE OR INCLUDE_SPEAK = TRUE THEN
$IF SPEAK_BM = UNDEFINED THEN
$LET SPEAK_BM = TRUE
$IF WIN THEN
SUB Speak (text AS STRING, Speaker AS INTEGER, Speed AS LONG)
DIM AS STRING message, remove
DIM out$
DIM AS LONG j, i
message = text
'some symbols and such can't be used with Powershell like this, as they're command symbols
'we need to strip them out of our text. (Like apostrophes!)
remove$ = "'" + CHR$(34) 'add to remove$ here, if more symbols need to be removed as future testing showcases problems
FOR j = 1 TO LEN(remove$)
DO
i = INSTR(message, MID$(remove$, j, 1))
IF i THEN message = LEFT$(message, i - 1) + MID$(message, i + 1)
LOOP UNTIL i = 0
NEXT
out$ = "Powershell -Command " + CHR$(34)
out$ = out$ + "Add-Type -AssemblyName System.Speech; "
out$ = out$ + "$Speech = New-Object System.Speech.Synthesis.SpeechSynthesizer; "
IF Speaker = 0 THEN out$ = out$ + "$Speech.SelectVoice('Microsoft David Desktop'); "
IF Speaker = 1 THEN out$ = out$ + "$Speech.SelectVoice('Microsoft Zira Desktop'); "
IF Speed THEN out$ = out$ + "$Speech.Rate =" + STR$(Speed) + "; "
out$ = out$ + "$Speech.Speak('" + message + "');" + CHR$(34)
SHELL _HIDE out$
END SUB
$ELSE
Sub Speak (dummy as string, dummy1 as Integer, dummy2 as long)
BEEP
_MESSAGEBOX "Warning!", "Notice: SUB Speak is a Windows-Only routine, as it relies upon Powershell to do its work. This routine does not work on Linux or Mac.", "warning"
End Sub
$END IF
$END IF
$END IF
$IF INCLUDE_ALL = TRUE OR INCLUDE_SCREEN = TRUE OR INCLUDE_BORDERWIDTH = TRUE THEN
$IF BORDERWIDTH_BM = UNDEFINED THEN
$LET BORDERWIDTH_BM = TRUE
FUNCTION BorderWidth&
$LET GLUTGET = TRUE
BorderWidth = glutGet(506)
END FUNCTION
$END IF
$END IF
Now, the above is from the new toolbox which I'm assembling on github. The idea here is to allow the user the flexibility to ONLY add what routines they want into their code, to reduce size and memory usage as much as possible.
Want all three routines? $LET INCLUDE_ALL = TRUE <-- one line of code at the top of your program and they're all included.
Only want the two screen routines? $LET INCLUDE_SCREEN = TRUE <-- again, one line of code which only enables those two routines.
Only want one particular routine? $LET INCLUDE_SPEAK = TRUE <-- and now we're only including the powershell text-to-speech routine.
And another trick which I've learned over the last few years?
Code: (Select All)$IF BORDERWIDTH_BM = UNDEFINED THEN
$LET BORDERWIDTH_BM = TRUE
FUNCTION BorderWidth&
$LET GLUTGET = TRUE
BorderWidth = glutGet(506)
END FUNCTION
$END IF
With the above wrapped around the sub/function, it doesn't matter if multiple libraries include the routine. It doesn't matter if it's in half a dozen $INCLUDE files. The first one that calls it will set the precompiler flag for it, and it'll be excluded when it comes to the rest of those routines.
No more "Duplicate Definitions" or "Name already in use" or whatnot errors.
And take this practice, along with the idea of moving your DECLARE LIBRARY code to the end of your source as I suggested in the first post here, and you can easily use one library to hold a whole collection of subs and functions, and only include the specific ones you need into your program. Just make certain that if one of the required programs uses a different routine inside the library, that it sets the independent flag to make certain that requite routine is also enabled. (Like with the glutget routines in my first post.)
I'm *still* sticking to the old set and true rules that we invented all those years ago -- I'm just learning to expand my tricks and building upon those rules in an attempt to make my stuff both more flexible and less error prone in the future.
No problem with all that, I like the idea with the glut stuff. I usually solved that problem by using ALIAS names, eg.
In LibOne:
DECLARE CUSTOMTYPE LIBRARY
SUB LibOne_memset ALIAS memset (BYVAL dest%&, BYVAL value&, BYVAL size&)
SUB LibOne_memcpy ALIAS memcpy (BYVAL dest%&, BYVAL sour%&, BYVAL size&)
SUB LibOne_strncpy ALIAS strncpy (BYVAL dest%&, BYVAL sour%&, BYVAL size&)
END DECLARE
In LibTwo:
DECLARE CUSTOMTYPE LIBRARY
SUB LibTwo_memset ALIAS memset (BYVAL dest%&, BYVAL value&, BYVAL size&)
SUB LibTwo_memcpy ALIAS memcpy (BYVAL dest%&, BYVAL sour%&, BYVAL size&)
SUB LibTwo_strncpy ALIAS strncpy (BYVAL dest%&, BYVAL sour%&, BYVAL size&)
END DECLARE
and then using the alias names in the respective libraries where I declared it, but finally they end up using all the same function in the linked EXE.
another thing I came up with, is to implement version strings into all my libraries and tools,
see here: https://qb64phoenix.com/forum/showthread.php?tid=2220
GuiTools, Blankers & other Projects:
https://qb64phoenix.com/forum/forumdisplay.php?fid=32
Libraries & useful Functions:
https://qb64phoenix.com/forum/forumdisplay.php?fid=23
https://qb64phoenix.com/forum/forumdisplay.php?fid=32
Libraries & useful Functions:
https://qb64phoenix.com/forum/forumdisplay.php?fid=23