another new data type: structs and static arrays

BlitzMax Forums/BlitzMax Programming/another new data type: structs and static arrays

Fabian.(Posted 2006) [#1]
In some situations (for example when interfacing with the winapi) it would be usefull to have something like c-structs as new variable data types in BMX. It could look like this:
Strict
Framework brl.blitz

Local Point:{ X , Y }
GetCursorPos Varptr Point
WriteStdout "Current Cursor Pos: " + Point.X + ", " + Point.Y + "~n"

Extern "Win32"
  Function GetCursorPos ( Point:Byte Ptr )
EndExtern
I know it looks a bit like c-code, so it invites to write unreadable code, however when interfacing with winapi and c functions this can be usefull and much faster than you have to write now. Since we don't have something like structs we have currently to work like either this:
Strict
Framework brl.blitz

Local Point [ 2 ]
GetCursorPos Point
WriteStdout "Current Cursor Pos: " + Point [ 0 ] + ", " + Point [ 1 ] + "~n"

Extern "Win32"
  Function GetCursorPos ( Point:Byte Ptr )
EndExtern
or this:
Strict
Framework brl.blitz

Local Point:TPoint = New TPoint
GetCursorPos Point
WriteStdout "Current Cursor Pos: " + Point.X + ", " + Point.Y + "~n"

Type TPoint
  Field X , Y
EndType

Extern "Win32"
  Function GetCursorPos ( Point:Byte Ptr )
EndExtern
It's a bit loss of speed, since the memory needs to be allocated from the system if you write the code this way - it would be faster if we could allocate the memory on the stack;

however you already can allocate this memory from the stack with this workaround:
Strict
Framework brl.blitz

Local Point:Long
GetCursorPos Varptr Point
WriteStdout "Current Cursor Pos: " + ( Int Ptr Varptr Point ) [ 0 ] + ", " + ( Int Ptr Varptr Point ) [ 1 ] + "~n"

Extern "Win32"
  Function GetCursorPos ( Point:Byte Ptr )
EndExtern
But this workaround can only help if your struct is 8 bytes or smaller in size - it can't fully replace structs, for example if you need a TRECT struct, which is 16 bytes long, till now you can't allocate this memory from the stack, so you have to write either:
Strict
Framework brl.blitz

Local Rect [ 4 ]
GetWindowRect GetDesktopWindow ( ) , Rect
WriteStdout "Desktop Resolution: " + Rect [ 2 ] + ", " + Rect [ 3 ] + "~n"

Extern "Win32"
  Function GetDesktopWindow ( )
  Function GetWindowRect ( Win , Rect:Byte Ptr )
EndExtern
or:
Strict
Framework brl.blitz

Local Rect:TRect = New TRect
GetWindowRect GetDesktopWindow ( ) , Rect
WriteStdout "Desktop Resolution: " + Rect.X2 + ", " + Rect.Y2 + "~n"

Type TRect
  Field X1 , Y1 , X2 , Y2
EndType

Extern "Win32"
  Function GetDesktopWindow ( )
  Function GetWindowRect ( Win , Rect:Byte Ptr )
EndExtern
both wouldn't be as fast and easy to use as:
Strict
Framework brl.blitz

Local Rect:{ X1 , Y1 , X2 , Y2 }
GetWindowRect GetDesktopWindow ( ) , Varptr Rect
WriteStdout "Desktop Resolution: " + Rect.X2 + ", " + Rect.Y2 + "~n"

Extern "Win32"
  Function GetDesktopWindow ( )
  Function GetWindowRect ( Win , Rect:Byte Ptr )
EndExtern
maybe this feature request is a bit far away from the way BlitzMax is developed and designed by now, however this feature would help in some cases to do speed optimizing and easier interfacing with operating system's functions.

Also a nice feature could be to have something like static arrays like they are used in some win32 data structs, for example the ToolTip field in the NotifyIconData struct; to implement this struct as BMX type, you've currently to write something like this:
Type TNotifyIconData
  Field Size
  Field Win
  Field ID
  Field Flags
  Field CallbackMessage
  Field Icon
  Field Tip00:Long
  Field Tip01:Long
  Field Tip02:Long
  Field Tip03:Long
  Field Tip04:Long
  Field Tip05:Long
  Field Tip06:Long
  Field Tip07:Long
  Field Tip08:Long
  Field Tip09:Long
  Field Tip10:Long
  Field Tip11:Long
  Field Tip12:Long
  Field Tip13:Long
  Field Tip14:Long
  Field Tip15:Long
EndType
Windows defines that the tooltip must be placed directly in the data struct, so if you want to implement this struct as BMX-type you have to create 32 integer fields or 16 long fields (like in the code I posted); both isn't the best way to solve the problem - it would be much better if we could write something like:
Type TNotifyIconData
  Field Size
  Field Win
  Field ID
  Field Flags
  Field CallbackMessage
  Field Icon
  Field ToolTip:Byte { 128 }
EndType


Just to make the difference clear between types/arrays and structs/static arrays:
The actual difference between a type and a struct is that when declaring a variable of that type you just have a reference to the object, a struct however would be a variable consisting of other variables.
The same with arrays and static arrays; a BMX-array is an object, so you also have a pointer to the object in memory; if you're using a static array variable in contrast you'll have a variable which directly contains the data.

So finally I just posted this feature suggestion here to hear some comments from you and BRL about how you think about it, and whether it could possibly be added to the BMX-language anywhere in the future.


ohahaha(Posted 2006) [#2]
Yes, physics stuff also needs these things.
Numerous vectors are generated and destroyed for a loop.
User defined type is too slow.


SebHoll(Posted 2007) [#3]
Bump... Any official comments?


Chris C(Posted 2007) [#4]
I asked for this ages ago, basically Mark didn't seem to see the need which is a shame

I'm sick of writing bits of C code to work out how far I need to offset from a pointer 'cause I cant use a C struct in max


Scaremonger(Posted 2007) [#5]
With Struct's we'd also have the ability to change data types:

Local oShort:TShort = New TShort
Local oByte:TWord

oShort.value = 257
oByte = TWords( obj )

Print "SHORT=" + oShort.value
Print "HI=" + oByte.hi
Print "LO=" + oByte.lo

Type TSHORT
	Field value:Short
End Type

Type TWORD
	Field hi:Byte
	Field lo:Byte
End Type


Structs would also allow a Struct to be overlaid onto a Bank to allow access to the data directly. In fact, a bank is already the basis of this new data type.


Jake L.(Posted 2007) [#6]
Using c-structs would make interfacing with libs much easier, so I vote for it, too.

Perhaps we should start a collection and ship some sweets and candy to Mark to turn him into the right mood. Anyone got his adress? ;)


BlitzSupport(Posted 2007) [#7]
I'd actually like this myself for direct Win32 API/DLL stuff. Peeking and poking at offsets in a Type isn't funny!


Who was John Galt?(Posted 2007) [#8]
Yeah I add another vote for it. I have brought the subject up a couple of times before.


Who was John Galt?(Posted 2010) [#9]
Well, I know I'm grave digging with this thread, but is there any possibility?

Is there any way in blitz to just stack allocate a block of memory?