View Full Version : UDT-improvement
ReneMiner
27-02-2018, 06:44
Udt - improvement
Just thoughts...:
The UDTs in tB already have properties and functions.
Quite good so far.
What will be next?
We know from other languages events on GUI-controls (buttons, textboxes etc.) as "_click()", "_gotFocus()".
Did you know that the UDTs in thinbasic already have EVENTS ?
Currently there's ._create() and ._destroy() only - but it shows a direction.
The difference is, event-functions-names in let's say visual basic are composed of the variables name and the event name, not separated by a dot but just like "Button1_Click()".
How good thinbasic supports already:
Dim vN As String ' holds variables name
Dim eN As String ' holds events name
Call_IfExists "" & vN & eN {(parameters)}
...
ReneMiner
28-02-2018, 09:44
What does the above mean?
If a variable of some user-defined-type >>UDT<< shall have user-defined-events the variable of our UDT needs a name. Quite simple to provide, just add a Name$-property and if more than one object with this name shall be possible suggest to add an Index-property too.
Do not get confused: the objects variable-name is not equal to the objects name.
Check this:
Type tButton
Name$ As String
Index As Long
End Type
Dim Buttonvar(123) As tButton
Buttonvar(1).Name$ = "myButton"
The variables name is "Buttonvar", the actual buttons name stored in Buttonvar(1) is "myButton", the variables Index is 1 while the Index of the stored object still remains 0 - not assigned.
Think...
to be continued
ReneMiner
28-02-2018, 16:37
No matter if the objects in an array are GUI-controls as buttons, textboxes etc. or soldiers, cannons and tanks in the players army or whatever... you will want to store their data in some array.
Hmm - an array? How can objects of different types be stored in an array you will ask, arrays consist of variables or UDTs that are all the same type.
You're right. Even if for example all GUI-controls have the same basic properties as position, size, visibility, name and index they all differ somehow. A textbox might have scrollbars and accept keyboard-input while a button only can be clicked. How can we store completely different sized items in an array so it's possible to process them one after the other?
The solution is simple: store only the pointers of all the objects in the array!
This will make another property necessary where we can store the information of what type the object at this pointer is.
Type$ As String
Because this is very basic and important information we should find it at the beginning of every items UDT-structure.
At the beginning: allows us without further calculation to read out the type-name at the pointer that is stored in the above described array.
So what we have?
Type tBasicObject
Type$ As String
Name$ As String
Index As Long
End Type
This is the basic information that all objects will share. Any user-defined-object can be an extension of this basic type
...more later
ReneMiner
05-03-2018, 06:47
The next step is to think about should this tBObject (t for Type, B for Base/Basic) be part of core-engine, a Module or just an #Include-File?I guess as #Include should serve as long as there's no hard-coded but only user-defined-events. Also some additional common properties as "Bit-flags, Visible, Enabled, Position (2d or 3d), width, height, (depth)..." can simply be added by the user to his desired kind of base-type.Only be aware to keep Type$,Name$ and Index as the first 3 properties.
ReneMiner
06-03-2018, 05:44
Now let's order this in a simple example:Assumed our objects are just geometric shapes as triangles, rectangles and circles drawn in 2d.What will all of these have in common?
Type tBasicShape ' information of type and identity Type$ as String Name$ as String Index as Long ' ability to enable and disable events ' like clicking or dragging Enabled as Boolean ' visibility - (if not visible it's not ' necessary to process this object) Visible as Boolean ' an individual color Red as Byte Green as Byte Blue as Byte ' a location where this object will appear ' we might calculate it somehow so it should ' be more precise than Integer or Single PosX as Double PosY as Double ' that should be enough properties for the meantime End TypeFor the position we will always use the center of the object and calculate all other points/corners/radius or whatever our object defines in relation to the centers position. Now let's setup the types for 3 kinds of objects:
Type tShapeRectangle Extends tBasicShape ' it has 4 corners CornerX(4) as Double CornerY(4) as Double ' and it gets drawn it's own way: Function DrawIt() ' UseColor (Me.Red, Me.Green, Me.Blue ' now here we calculate the 4 positions of ' the corners and draw a rectangular shape End FunctionEnd TypeType tShapeTriangle Extends tBasicShape ' has 3 corners CornerX(3) as Double CornerY(3) as Double Function DrawIt() UseColor (Me.Red, Me.Green, Me.Blue) ' calculate the corners position and draw End FunctionEnd TypeType tShapeCircle Extends tBasicShape Radius As Double Function DrawIt() ' guess... End FunctionEnd Type...
ReneMiner
10-03-2018, 11:16
Him, strange, I cannot edit the post above to bring the code in readable lines...
Nevertheless, continue:
We have a base type and a few that Extends it. All extensions "know" what type they are of, have Names and Indexes.
Now we have to think about to collect the pointers of all the object into an array. That will allow to loop and cycle through all our objects, no matter if it's a circle, triangle or rectangle. A layover of the basic-type at the pointer that is stored in the array will inform us about Type, Name and Index already and if we use Dim-Like-syntax it is very easy to call the specific functions and access the properties of the actual type. Only keep in mind if you
Function drawAllObjects()
' this is not a Type-Funtion of tBasicType nor of its extensions!
Long i
Dim basicObject as tBObject At 0
For i = 1 to Ubound (myPtrs)
SetAt(basicObject, myPtrs (i))
' now call tBasicType-function:
If basicObject.DrawToCanvas Then Nop
Why like this?
Inside the function DrawToCanvas we will use dynamic type-declaration of the actual extending type. To make sure it works correctly we have to request the functions result even if we don't need to use it...
So far.
Function tBObject.DrawToCanvas()
' create layover of the extension at same pointer:
Local myObject Like Me.Type$ At Varptr(Me)
' now we call drawing function of the actual object
myObject.DrawToCanvas()
'...
OK so far. I hope you understand until here
Assume we also have functions that check if the mousepointer is currently pointing one of our objects and if left mousebutton goes down we will call:
Call_IfExists "" & basicObject.Name$ & "_click" (basicObject. Index)
If we have a rectangle that's Name$ property holds "myRect" then we should have a
Sub myRect_click(Byval Index As Long)
' Index will receive the passed content of tObjectRectangle.Index
End Sub
Hmm...
How we store the different objects?
At Heap of course!
If we would make one array of circles, one for triangles and another one for the rectangles, what you think - will their pointers still be valid after we redim to add or remove one object?
Surely not. So we have to store every object at heap-memory and save the pointers in some DWord-Array. Pointers will never be negative numbers and there's an arsenal of array-functions contained in thinbasic that are ready to work with pointer-arrays (check help for thincore's Array-Functions that contain parameters as "DWord" and "Ptr")
Mandatory all objects must be fixed size, means no udt-property must have dynamic arrays. Also for properties that shall contain string-data I would recommend to use DWord's instead and store the desired data at heap.
...
So far, difficult to type all this on a mobile phone, with my next post I will come to the first of my improvement-ideas
;)
ErosOlmi
12-03-2018, 08:02
Him, strange, I cannot edit the post above to bring the code in readable lines...
http://www.thinbasic.com/community/showthread.php?12794-IMPORTANT-Change-in-forum-rules
ReneMiner
12-03-2018, 16:17
Thanks Eros for reminding me - and everything else ;)
Now my first idea: we have several objects of different type, some of them have similar properties that others don't have, for example a .Width or .Text-property and those properties shall behave similar so I don't like to repeat writing the same code over and over again I would usually create an UDT (example tWidth) give it some desired functions (like .Enlarge(...) or .Reduce(...) ) and then I create the other UDT and give it a property
Width As tWidth
Actually the width is one numeric variable like "Long" only, so if .Width becomes a sub element of another UDT and has functions i have to give the Type tWidth a property lWidth to store the value.
Type tWidth
lWidth As Long
Function Enlarge(Byval howMuch As Long) As Long
'...
End Function
'...
End Type
Type tButton Extends tBObject
Width As tWidth
'...
End Type
If I want the width of a button I have to use
myButton.Width.lWidth
Is there a way that
myButton.Width can just access the very first/only property of tWidth?
Can it be that the first property of an UDT|Union is it's default-property?
ReneMiner
16-03-2018, 09:12
Perhaps like
Type tType
Public
Default
defaultProperty As Long
'...
End Type
Dim x As tType
Every time if just "x" is used it means to use "x.defaultProperty".
The default property must be public of course
ReneMiner
20-03-2018, 02:47
Hmm, no reply yet...
But another question into that direction:
Could "Heap" be a built-in functional UDT (or module)?
I mean somewhat like
Alias DWord As Heap
where the DWord stores the pointer and we can just use it like
Dim x(123)As Heap
X(1).Allocate (nBytes)
' equal to currently
X(1) = Heap_Allocate (nBytes)
but also we could treat X(123) like a DWord-Array at the same time?
All Heap-functions should be available using dot-notation to a variable declared as heap but actually the array should be treated/stored likewise DWord....
???
ReneMiner
20-03-2018, 05:05
Another one:
With tMyUdt At pData
.property = ...
.functionName(parameters)
End With
Alias
Dim x As tMyUdt At pData
With x
.property = ...
.functionName(parameters)
End With
Would it be possible to use functions and properties of an UDT just providing the pointer? So not need to
Dim varName As tType At dataPtr
With varName
...
End With
but
With tType At dataPtr
...
End With
Using it this way ._Create() or ._Destroy() would not be executed of course