All others, might want to read on. First a small Q & A, about optimizing a
common rectangle type (called: Rect_t):
Code: Select all
' a commonly seen rectangle-type: a truly memory wasting beast (as soon as arrays are used)
Type Rect_t ' NOTE: alignment means, without 'field = 1' statement
As Integer _x, _y, _w, _h ' FBC32 = 20 Bytes | FBC64 = 36 Bytes (alignment = 40)
As ULong _c ' Question: can't we do any better?
End Type ' Answer: yes, we can optimize quite a lot
' first step: get rid of 'Integer' (use fixed size int-types)
Type Rect_t ' see below
As Long _x, _y, _w, _h ' FBC32 = 20 Bytes | FBC64 = 20 Bytes | equal size
As ULong _c ' Question: is this all really needed?
End Type ' Answer: not really, there are non essential parts
' second step: remove what is not essential
Type Rect_t ' FBC32 = 8 Bytes | FBC64 = 8 Bytes | equal size
As Long _w, _h ' Question: do we really need a 32 bit int-type?
End Type ' Answer: not really, a 16 bit int type is large enough
' third step: reduce type size (to a level conformant to current/tomorrows screen sizes)
Type Rect_t ' FBC32 = 4 Bytes | FBC64 = 4 Bytes | equal size
As Short _w, _h ' Question: do we have a option to speed up?
End Type ' Answer: yes, we can use the unsigned equivalent
' fourth step: use unsigned instead of signed (signed is not reqired here)
Type Rect_t ' FBC32 = 4 Bytes | FBC64 = 4 Bytes | equal size
As UShort _w, _h ' Question: do we have all that is needed?
End Type ' Answer: yes, all there and mem./speed optimized
But I'm willing to show, that a tiny type like above (shrunk to 4 Bytes size) is,
in fact all that is really needed, to put a simple rectangle to screen ...
For ease of use and, for re-usability I've made a .bi file (containing all type
related stuff), called:
Rect_t.bi (whole implementation):
Code: Select all
' Rect_t.bi -- 2018-08-09, MrSwiss
'
#Pragma Once ' only loaded once (include guard)
' ----- start type -----
Type Rect_t ' a very basic rectangle type (only: width/height, held internally)
Private: ' no direct user access (to variables)
As UShort w, h ' variables (unsigned 16 bit integer)
Public: ' interface (gives some rights, to user)
Declare Constructor(ByVal w1 As UShort, ByVal h1 As UShort) ' construct & assign values
' actor: put rectangle to screen at: x/y, with color: clr and fill: fll (default=FALSE=NOT filled)
Declare Sub show(ByVal x As Short, ByVal y As Short, ByVal clr As ULong=&hFF7F007F, ByVal fll As Boolean=FALSE)
Declare Sub setn(ByVal nw As UShort=0, ByVal nh As UShort=0) ' setter: change current values
Declare Sub getv(ByRef wt As UShort=0, ByRef ht As UShort=0) ' getter: returns stored values
' no need for a Destructor (default by compiler, does 'the trick')
End Type
'
Constructor Rect_t( _ ' user defined copy-constructor (incl. assign)
ByVal w1 As UShort, _ ' width, mandatory
ByVal h1 As UShort _ ' height, mandatory
)
This.w = w1 - 1 : This.h = h1 - 1 ' correction for: relative sizing of RECT
End Constructor
'
Sub Rect_t.show( _ ' actor: put rectangle to screen
ByVal x As Short, _ ' x position, mandatory (signed 16 bit integer)
ByVal y As Short, _ ' y position, mandatory (signed 16 bit integer)
ByVal clr As ULong=&hFF7F007F, _ ' 32 bit color (default = purple), optional
ByVal fll As Boolean=FALSE _ ' default, not filled Box, optional
)
If fll Then ' if fll=TRUE then, show Box filled
Line (x, y)-Step(This.w, This.h), clr, BF ' Step = width/height are relative to x/y
'Line (x, y)-(x + This.w, y + This.h), clr, BF ' absolute positioning
Else ' otherwise, show Box NOT filled (default)
Line (x, y)-Step(This.w, This.h), clr, B
End If
End Sub
Sub Rect_t.setn( _ ' set new value(s), default: do nothing
ByVal nw As UShort=0, _ ' optional new width
ByVal nh As UShort=0 _ ' optional new height
)
If nw > 0 Then THis.w = nw - 1 ' correction for: relative sizing of RECT
If nh > 0 Then THis.h = nh - 1
End Sub
Sub Rect_t.getv( _ ' get currently set value(s)
ByRef wt As UShort=0, _ ' optional width (if var. provided)
ByRef ht As UShort=0 _ ' optional height (if var. provided)
)
wt = This.w + 1 : ht = This.h + 1 ' correction for: real size
End Sub
' ----- end type -----
Code: Select all
' simplest_RECTANGLE_type.bas -- 2018-08-10, MrSwiss
'
' compile: -s gui
'
#Include "Rect_t.bi" ' load the rectangle type
' macros ...
#Define RndARGB ( CULng(Rnd * &hFFFFFFFFul) ) ' all color32 random, incl. alpha
#Define RngShrt(l, h) ( CShort(Rnd * ((h) - (l)) + (l)) ) ' random number from a defined range
Const As UShort scr_w = 1280, scr_h = 768, _ ' this two can be adjusted, by user
cd = 32, pg = 2, fg = 64 ' this stuff must remain unchanged!
' ===== start main =====
ScreenRes(scr_W, scr_h, cd, pg, fg) ' window sizes | 32 bit color | 2 pages | using alpha
Var sp1 = 1, sp2 = 0 ' screen pages (for buffer swapping)
ScreenSet(sp1, sp2) ' pre-set first buffer (to be drawn/shown)
Dim As Rect_t Ptr prec(1 To 30) ' array of rect_t ptr (number of rectangles)
Dim As Short lba = LBound(prec), uba = UBound(prec) ' store current array definitions
Dim As short tl_offs = -(scr_h Shr 4) ' top/left offset (based on assumed smaller size)
Dim As Boolean flg1 = TRUE ' process control (fill, no fill)
For i As UInteger = lba To uba ' initialize the ptr array (copy constructor call)
prec(i) = New Rect_t(RngShrt(scr_W * .1, scr_w * .4), _ ' min. = 10% | max. 40% (of width)
RngShrt(scr_h * .05, scr_h * .3)) ' min. = 5% | max. 30% (of height)
Next ' use macros for sizing (fixed min/max aspect ratio's _
' but, based on current screen sizes used)
Do
If Len(InKey()) > 0 Then Exit Do ' on user action --> EXIT LOOP (quit prog.)
Cls
For i As UInteger = lba To uba ' rectangles to screen (using macros for pos. & color)
prec(i)->show(RngShrt(tl_offs, scr_w - tl_offs), _ ' positioning wit offset, based _
RngShrt(tl_offs, scr_h - tl_offs), _ ' on the current width/height used
RndARGB, flg1) ' random color | fill/no fill (switches each run!)
Next
Draw String (30, 21), "type size: " + Str(SizeOf(*prec(lba))) ' show types size (4 bytes)
Swap sp1, sp2 : ScreenSet(sp1, sp2) ' swap visible/working page (show latest drawn buffer)
flg1 = Not flg1 : Sleep(500, 1) ' invert flag | free some CPU (let user see it 0.5 sec.)
Loop
' clean up ...
For i As UInteger = lba To uba ' whole array (free allocated ptr's memory)
Delete(prec(i)) ' delete ptr's (default destructor call)
Next
' ===== end main ===== ' ----- EOF -----