PDA

View Full Version : passing virtual type ByPtr?



ReneMiner
24-05-2013, 10:46
Topic sounds stark mad, but I'll try to explain:

I have some UDT as Gadgets (GUI-Controls). Since not every control has the same properties I want to make some pointer on my Gadget-Type that points to the data of the single Gadgets. Example:



Type t_Gadget
sName as String
'...the Main-Type
pData as Dword
'....
End Type

Dim Gadget() as t_Gadget

Type t_Timer
' example Sub-Type of some Gadget:
Interval As DWord
TimeOut As DWord
End Type



Now when it comes to some event, for example a timers time is up i want to call a user-sub as this


Call_IfExists Gadget(X).sName + "_TimeIsUp" ( Gadget(X).pData )

' now the sub should work as this:

Sub myTimer_TimeIsUp( ByPtr lTimer As t_Timer )

' now inside this sub I would like to have lTimer as virtual memory-overlay at byval Gadget(X).pData as t_Timer

End Sub

I know, I could just setup the sub as this:


Sub myTimer_TimeIsUp( Byval myPtr as Dword )
Local lTimer as t_Timer At myPtr
'....


but I would like to hide all that "complicated" stuff from the user on the one hand, on the other I don't like to create an unnecessary local variable first (byval myPtr) which will neutralize the speed-advantage of virtual overlay again.

Edit-Extended thoughts:



Type t_someFixedSizeType
A as Long
B as Byte
C as Double
End Type

Dim myHeap As Dword = Fill_In_Data(0, 1, 2, 3.5)
myHeap = Fill_In_Data(myHeap, 2, 3, 4.5)
myHeap = Fill_In_Data(myHeap, 3, 4, 5.6)
'...

ShowMyData(myHeap)
'...

Function Fill_In_Data(Byval oldPtr as Dword, Byval A as Long, byval B as Byte, byval C as Double) as Dword

Local lData as t_someFixedSizeType
lData.A = A
lData.B = B
lData.C = C

If oldPtr = 0 Then
Function = Heap_AllocByStr( Peek$(VarPtr(lData), SizeOf(t_someFixedSizeType)) )
Else
Local sData as String = Peek$(oldPtr, Heap_Size(oldPtr)) + Peek$(VarPtr(lData), SizeOf(t_someFixedSizeType))
Local newPtr = Heap_ReAlloc( oldPtr, len(sData) )
if newPtr Then Poke$(newPtr, sData)
Function = newPtr
Endif


End Function

Sub ShowMydata( ByHeap something() As t_someFixedSizeType )

' inside sub now have a virtual array of someFixedSizeType placed
' over passed Heap-Pointer with element-count of Heap_Size()/SizeOf(t_someFixedSizeType)
' if no parenthesis behind something means single element only - which is the same as ByPtr...

local i as Long

For i = 1 to UBound(something)
Print Something(i).A
Print Something(i).B
Print Something(i).C
Next


End Sub

Petr Schreiber
25-05-2013, 09:38
Maybe this solves the issue of passing multiple ~types using single generic parameter.

How does it work?

You have specific types for specific controls, GadgetButton, GadgetLabel, ...
You have one master type, GadgetMultiUDT, which could contain the type of gadget + data, which have all gadgets in common + Union, which allows to access store/retrieve data for any type


Little example here:


' -- Gadget types
Begin Const
%Gadget_TypeButton
%Gadget_TypeLabel
End Const

' -- Gadget specific data
Type GadgetButton
OnClickFunction As String
End Type

Type GadgetLabel
IsMultiline As Long
End Type

' -- Union to collect all possible gadgets
Union GadgetsAll
gButton As GadgetButton
gLabel As GadgetLabel
End Union

' -- UDT with type identifier
Type GadgetMultiUDT
gType As Long

caption As String
x As Long
y As Long
width As Long
height As Long

gData As GadgetsAll
End Type

Function TBMain()
Dim myButton As GadgetMultiUDT
myButton.gType = %Gadget_TypeButton
myButton.caption = "Click me" ' -- Shared data
myButton.x = 5
myButton.y = 5
myButton.width = 100
myButton.height = 20
myButton.gData.gButton.OnClickFunction = "myButton_OnClick" ' -- Control specific data

Dim myLabel As GadgetMultiUDT
myLabel.gType = %Gadget_TypeLabel ' -- Shared data
myLabel.caption = "Some text" + $CRLF + "And more of it"
myLabel.x = 5
myLabel.y = 5
myLabel.width = 100
myLabel.height = 20
myLabel.gData.gLabel.IsMultiline = TRUE ' -- Control specific data

Gadget_DoSomething(myButton)
Gadget_DoSomething(myLabel)
End Function

Function Gadget_DoSomething( g As GadgetMultiUDT ) ' -- You can pass any control here

Select Case g.gType
Case %Gadget_TypeButton
MsgBox 0, "It's a button: data = " + g.gData.gButton.OnClickFunction

Case %Gadget_TypeLabel
MsgBox 0, "It's a label: data = " + Format$(g.gData.gLabel.IsMultiline)
End Select

End Function



Petr

ReneMiner
25-05-2013, 09:47
So Unions can have different length - this not a problem nor waste of memory?

ErosOlmi
26-05-2013, 11:29
So Unions can have different length - this not a problem nor waste of memory?

Hi Rene,

it is not exact to say Unions have different length but instead it is exactly the opposite:

an Union size is the size of the maximum element included inside the Union so all Unions of the same type have the same length
all elements inside an Union share the same memory area


If inside an union you have a byte and a long, the union is 4 bytes (long)
Union MyUnion
b As Byte
l as Long
End Union
The difference is how you interpret that memory:

when you access b (the single byte) you are changing a byte
when you access l (the single long, 4 bytes) you are changing all 4 bytes including b byte because the memory area is the same, you are just interpreting it in different ways.


Yes, there is a little waste of memory when there are big differences of types inside the same Union but unless you have many many thousands of them, it is not something you have to consider.

Ciao
Eros

ReneMiner
27-05-2013, 07:35
OK, I see now that united subsets don't need all the same length -there can be some leftover.
Still I would like to hide all my variables and use heap instead of some global array for controls. I know it works with Dim At myPtr and it would be great if the function call could already do the "dim at" so the later user won't/can't fool around with my passed pointer to heap and gets some object-like variable presented