Audience: beginners (with some experience) / advanced
Skills required: understands procedures (sub/function), with one or more parameter's and (maybe) overload(ing)
Terms used:
- UDT = user defined type
overload(ed) constructor (superseeds default procedure, in the chain of events)
ctor = constructor (default or overloaded)
dtor = destructor (default)
[/header]
Object Encapsulation
WHY:
To allow the programmer of a Type/Class or even a whole library, to:
- actively control the access to its internals (pointers/variables etc.), none/read only/write only/read & write
- secure operations, by denying certain destructive user actions (like pointer overwriting, deallocating etc.)
HOW:
In order to "get" control, we have to first deny all external access, by labeling all internals as *PRIVATE*.
Excerpt from below code:
Code: Select all
Type image ' takes ImageCreate()/-Destroy()/ImageInfo() from the user (automatic handling)
Private: ' prevent direct user access = IMPORTANT!
As Any Ptr pimg ' image ptr (user: read only!)
As String descr ' image description, title or name (user: read/write)
Public:
' Abstraction starts here ...
End Type
Abstraction
In order to *selectively* return some access rights to user, we have to use Abstraction (remember: user has none rights, any longer).
Abstraction, also referred to as Interface, in its simplest form, has usually three/four distinctive types of methods:
1) "generate a user Object" method: constructor (overloaded), more than one possible (user callable)
Code: Select all
Var pt = New image(100, 100, RndARGB)
Code: Select all
Delete pt
- getter examples:
get_def() (Sub, ByRef return) retrieves: width/height/size of a image [changed name: 2018-06-07]
get_pval() (Function, no parameter) returns ptr address (debug/test use mostly)
setter example:
newdesc() (Sub) sets: a new or diferent image description
actor example:
showimg() (Sub) puts image to screen (at user given position and user chosen method)
Getter/Setter can also be achieved, by using "Property" statement, for more information on that, refer to the link, provided by fxm.
(Since this is for beginners also, I didnt want to introduce more complexity, than absolutely needed!) [added: 2018-06-07]
- = (assignement)
let (copy & assign) and so on ... (see FB-Manual, for details)
Additional info can be gotten from comments in below code (or ask in this thread):
Code: Select all
' Image-Type_test.bas -- 2018-06-04, MrSwiss (Rev. 1 -- 2018-06-07)
'
' compile: -s gui
'
Type image ' takes ImageCreate()/-Destroy()/ImageInfo() from the user (automatic handling)
Private: ' prevent direct user access = IMPORTANT!
As Any Ptr pimg ' image ptr (user: read only!)
As String descr ' image description, title or name (user: read/write)
Public:
' ctor / dtor
Declare Constructor(ByVal iw As UShort, ByVal ih As UShort, ByVal clr As ULong=&h00FF00FF00, ByRef n As Const String="")
Declare Destructor()
' subroutines
Declare Sub newdesc(ByRef nd As Const String) ' set or change description (e.g. if not set in ctor)
Declare Sub get_def(ByRef iw As UShort=0, ByRef ih As UShort=0, ByRef siz As ULong=0) ' get header info (w, h, size)
Declare Sub showimg(ByVal ix As Short, ByVal iy As Short, ByVal tr As Boolean=TRUE) ' display image (at pos. ix/iy)
' functions
Declare Function get_pval() ByRef As Const Any Ptr ' probably only used for debugging/testing
Declare Function get_desc() ByRef As Const String ' read image description
End Type
Constructor image(ByVal iw As UShort, ByVal ih As UShort, ByVal clr As ULong=&h00FF00FF00, ByRef n As Const String="")
This.pimg = ImageCreate(iw, ih, clr, 32) ' exlcusively 32-bit color! default: transparent
This.descr = n ' assign description (can be left empty)
End Constructor
Destructor image()
ImageDestroy(This.pimg) ' deallocate ptr (before type destruction) test only: _
End Destructor ' comment out above: to see a massive memory leak!!!
Sub image.newdesc(ByRef nd As Const String)
This.descr = nd
End Sub
Sub image.get_def(ByRef iw As UShort=0, ByRef ih As UShort=0, ByRef siz As ULong=0)
Dim As Integer w, h, s ' solely to satisfy: ImageInfo()
ImageInfo(This.pimg, w, h,,,, s) ' only get the important parts: width/height/size
iw = CUShort(w) ' convert & assign
ih = CUShort(h) ' dito
siz = CULng(s) ' dito
End Sub ' local vars. destroyed here (going out of scope)
Sub image.showimg(ByVal ix As Short, ByVal iy As Short, ByVal tr As Boolean=TRUE)
If tr Then
Put (ix, iy), This.pimg, Trans ' show the image with transparency
Else
Put (ix, iy), This.pimg, PSet ' show the image opaque (tr = FALSE)
End If
End Sub
Function image.get_pval() ByRef As Const Any Ptr
Return This.pimg ' provide read access to user
End Function
Function image.get_desc() ByRef As Const String
Return This.descr ' provide read access to user
End Function
' ----- end type -----
' preparation: define color randomizer & heat rnd() up
#Define RndARGB ( CULng(Rnd() * &hFFFFFFFFul) ) ' any 32-bit color (any alpha value)
Randomize( , 5) ' initialize randomizer (OS specific method)
for i As UInteger = 1 To 50 ' heat up randomizer (300 call's)
Rnd() : Rnd() : Rnd() : Rnd() : Rnd() : Rnd()
Next
' testing code, purpose: detect memory leaks (if any)
ScreenRes(800, 800, 32,, 64) ' using: GFX_ALPHA_PRIMITIVES (see fbgfx.bi)
Color(&hFF000000, &hFFFFFFFF) : Cls ' black on white bg
Width 800\8, 800\16 ' 8 x 16 Font
Dim As ULong cnt = 1, siz
Dim As UShort wid, hei
Do
Var pt = New image(100, 100, RndARGB) ' partly init (ctor without description)
pt->newdesc("Image" + Str(cnt)) ' add description (just for examples sake!)
'Var pt = New image(100, 100, RndARGB, "Image" + Str(cnt)) ' complete ctor call
pt->get_def(wid, hei, siz) ' get image definitions
If CsrLin = 50 Then Cls ' clear screen when getting full
Print Str(pt->get_pval), pt->get_desc, "w: "; wid; " h: "; hei; " size: "; siz
pt->showimg(650, 350) ' display image (fixed pos.)
Delete pt ' hidden dtor call (aka: indirect)
Sleep(20, 1) ' free some CPU resources
cnt += 1 : If cnt > 10000 Then cnt = 1 ' counter handling
Loop Until Len(InKey()) > 0 ' run, until user interrupts (=prog. end)
' ----- EOF -----
As noted in comments: commenting out "ImageDestroy()" in destructor, creates a massive *memory leak* (uncomment after test!!!).