Seite 1 von 1

BuildStructuredArray()

Verfasst: 13.08.2009 19:07
von cxAlex
Mit diesem Code kann man schnell und einfach ein strukturiertes Array dynamisch erstellen und "PB-Like" darauf zugreifen. Hält den Source übersichtlich.

Inkl. Subarrays.

Code: Alles auswählen

; ------------------------------------------------------------------------------------
; Build Structured Array
; Schnell dynamische Strukturierte Arrays erstellen
;
; Author: Alexander Aigner
; PB 4.3 +
; ------------------------------------------------------------------------------------

Macro _Macro1
  M
EndMacro

Macro _Macro2
  acro
EndMacro

Macro _Macro
  : _Macro1#_Macro2
EndMacro

Macro _EndOfMacro1
  EndM
EndMacro

Macro _EndOfMacro2
  acro
EndMacro

Macro _EndOfMacro
  : _EndOfMacro1#_EndOfMacro2
EndMacro

Macro FreeArray(_Array)
  FreeMemory(*_Array)
EndMacro

Macro FreeSubArray(_Array, _SubArray)
  If Not Defined(fsa_i, #PB_Variable)
    Define fsa_i
  EndIf
  For fsa_i = 0 To _Array#_Array_Size-1
    FreeMemory(*_Array#\Entry[fsa_i]\_SubArray)
  Next
EndMacro

Macro BuildHolder(_Structure)
  Structure _Structure#_Holder
    Entry._Structure#[0]
  EndStructure
EndMacro

Macro BuildStructuredArray(_Name, _Structure, _Size, _Scope = Global) 
  Define _Name#_Array_Size
  _Name#_Array_Size = _Size
  _Scope*_Name._Structure#_Holder
  *_Name = AllocateMemory(_Size*SizeOf(_Structure))
  
  _Macro _Name(_Index)
  *_Name#\Entry[_Index]_EndOfMacro
  
EndMacro

Macro BuildStructuredSubArray(_HolderArray, _HolderEntry, _Structure, _Size)
  If Not Defined(bssa_i, #PB_Variable)
    Define bssa_i
  EndIf
  
  For bssa_i = 0 To _HolderArray#_Array_Size-1
    *_HolderArray\Entry[bssa_i]\_HolderEntry = AllocateMemory(SizeOf(_Structure)*_Size)
  Next
  
  _Macro _HolderEntry(_Index)
  _HolderEntry#\Entry[_Index]_EndOfMacro
EndMacro

Macro StructuredArray(_Name, _Structure)
  *_Name#._Structure#_Holder
EndMacro

; Democode




; Demo - Struktur
Structure MyData
  Count.i
  *XData
  *Handle
  ; Subarray - Einträge
  StructuredArray(SubArray, MyData)
  StructuredArray(SubArray2, MyData)
EndStructure

; Holder für MyData-Struct erstellen
BuildHolder(MyData)

; Array erstellen
; Achtung, 10 Felder = 0-9
BuildStructuredArray(MyArray, MyData, 11)
; Subarray erstellen
BuildStructuredSubArray(MyArray, SubArray, MyData, 10)
BuildStructuredSubArray(MyArray, SubArray2, MyData, 10)

; Wert setzen
MyArray(1)\SubArray(3)\XData = 100
MyArray(2)\SubArray(4)\XData = 345
MyArray(2)\SubArray2(8)\XData = 123

; Wert lesen
Debug MyArray(1)\SubArray(3)\XData
Debug MyArray(2)\SubArray(4)\XData
Debug MyArray(2)\SubArray2(8)\XData

; Array freigeben
FreeSubArray(MyArray, SubArray)
FreeSubArray(MyArray, SubArray2)
FreeArray(MyArray)
Gruß, Alex

Verfasst: 13.08.2009 19:26
von Thalius
:allright:

Kreativ Cleverer einsatz von Macros :)

Verfasst: 13.08.2009 19:31
von Little John
:?:

Das geht doch auch mit nativen PB-Anweisungen:

Code: Alles auswählen

;-- Demo

Structure MyData
   Count.i
   *XData
   *Handle
EndStructure

; Array erstellen
Dim MyArray.MyData(10)

; Wert setzen
MyArray(1)\XData = 100

; Wert lesen
Debug MyArray(1)\XData
Gruß, Little John

Verfasst: 13.08.2009 19:36
von cxAlex
Jaja. Aber nur fix:

>Dim MyArray.MyData(10)

Damit kann man mit kleine Anpassungen z.B. Auch Arrays in Strukturen machen oder Arrays in LinkedLists() und PB - Like darauf zu greifen.

Verfasst: 13.08.2009 20:04
von cxAlex
Code verbesser (siehe 1. Post)

Nun mit beliebig vielen Subarrays. Zugriff natürlich auch PB - Like.

Das mit dem BuildHolder() ist noch etwas unschön, hab aber grade keine andere Lösung gefunden da Defined und Compilerif nur Konstante Werte akzeptieren und keine per Makro zusammengesetzten Ausdrücke. Mal schaun ob man da noch was machen kann.

Gruß, Alex

Verfasst: 13.08.2009 20:19
von Little John
cxAlex hat geschrieben:Jaja. Aber nur fix:

>Dim MyArray.MyData(10)
Was meinst Du in diesem Zusammenhang mit "dynamisch" bzw. "fix"?
Die zu verwendenden Structures müssen in beiden Fällen zur Compilezeit vorliegen, die Anzahl der Elemente kann in beiden Fällen zur Laufzeit bestimmt werden, und in beiden Fällen kann anschließend der Speicher wieder freigegeben werden.

Gruß, Little John

Verfasst: 13.08.2009 20:23
von cxAlex
Sieh dir mal meinen Code im 1. Post an. Das kann PB nativ nicht.
Klar ist nur nen Aufsatz aber was ist lesbarer:

MyArray(1)\SubArray(3)\XData = 100
*MyArray\Entry[1]\SubArray\Entry[3]\XData = 100

Außerdem übernimmt mein Code das allokieren und freigeben des verwendeten Speichers der Subarrays für jeden Eintrag des Mutterarrays, das erstellen der Holder... .Das müsste man sonst selbst machen.

Gruß, Alex

Verfasst: 13.08.2009 20:37
von Little John
cxAlex hat geschrieben:Sieh dir mal meinen Code im 1. Post an. Das kann PB nativ nicht.
In Bezug auf die erste Version Deines Codes hattest Du "dynamisch" und "fix" gegenübergestellt. Darauf bezogen sich meine Fragen.
Inzwischen hast Du den Code ja erweitert.
Allein schon daher ist es keine Anzwort, zu empfehlen dass ich mir jetzt die geänderte Version Deines Codes im 1. Post ansehen soll ....

Verfasst: 13.08.2009 20:40
von cxAlex
Im Bezug auf die 1. Version hast du recht, wollte die eigentlich etwas anders designen und bin erste nicht drauf gekommen dass das eigentlich ne 1:1 PB Kopie war.