Seite 1 von 2
CopyStructure und LinkedLists
Verfasst: 25.05.2011 11:12
von delikanli_19_82
hallo leute,
ich habe hier eine konzeptfrage. wenn man jetzt mit pb ein interface-objekt bastelt, so muss ja seine gesamtgröße eindeutig sein. arrays können ja nicht direkt in so ein interface untergebracht werden. kann man dieses problem mit hilfe des copystructure-befehls lösen? und falls ja, wäre das ein guter ausweg, oder doch eher nicht zu empfehlen, da ja die gesamte struktur im speicher kopiert wird. die alte könnte man ja dann mit clearstructure löschen.
falls das nicht geht, dann eine andere frage. gibt es irgendeinen vernünftigen weg, interface-objekte dazu zu bringen, intern arrays aufzunehmen und zu verwalten.
im moment habe ich das problem dadurch umgangen, das ich globale struktur-variablen mit entsprechenden linkedlists und einem id versehen habe. wenn ein objekt-instanz geladen wird, so wird im konstruktur eine interne id-nummer erzeugt und in der globalen struktur-variable ein neuer abschnitt angelegt und dort ebenfalls die id eingetragen. immer wenn ich mit dem instanz-x arbeite, springt dessen methode sicherheitshalber jedesmal per foreach, innerhalb dieser globalen linkedlist an die richtige stelle und erst dann werden die daten ausgewertet bzw. manipuliert.
mfg
kurt
Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 11:41
von NicTheQuick
Redest du von statischen Arrays oder von dynamischen Arrays? Die dynamischen Arrays kannst du doch ganz einfach in eine Structure einbauen, vorausgesetzt du hast ein aktuelles PureBasic.
Mach lieber mal einen kleinen Beispielcode, an dem wir das Problem genau verstehen können.
Danke!

Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 12:00
von delikanli_19_82
der nachfolgende code funktioniert nicht, soll aber sinnesgemäß das wiederspiegeln, was ich mir vorstelle, wie ich es ungefähr haben will:
Code: Alles auswählen
; um bestimmte aufgabenbereiche eines objekts zu gruppieren, bastelle ich mehrere strukturen, die die erwünschten
; bereiche zusammenfassen.
; position und volumn des objekts
Structure objektname_p_sz
x.l : y.l : w.l : h.l
EndStructure
; hier werden beispielsweise die daten zu einem Abschnitt gesammelt ( dieses beispiel ist fiktiv und soll eine komplexe array-struktur demonstrieren )
Structure objektname_con_ety
List txt.s()
List key.s()
List nbr.l()
EndStructure
; hier werden beispielsweise die daten gesammelt (dynamisch natürlich)
Structure objektname_con
list value.objektname_con_ety()
EndStructure
; Das Interface
Interface objektname
methode_a()
methode_n()
EndInterface
; Die Body-Struktur
Structure objektname_body
Tbl.l
Met.l[SizeOf(objektname)/4]
psz.objektname_p_sz
; HIER DAS WAS ICH EIGENTLICH MÖCHTE, EINE STRUKTUR
; DIE EINEN DYNAMISCHEN ARRAY (und unter umständen eben
; weitere Subarray ) ENTHÄLT.
con.objektname_con
EndStructure
...
Ich würde gerne eine solche oder ähnliche lösung haben, so das ich arrays in objekte integrieren kann, so das jedes
objekt seine eigene kopie der für ihn vorgesehenen linkedlists hat und damit arbeitet.
mfg
kurt
Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 13:18
von delikanli_19_82
hat sich erledigt. habe eine lösung gefunden

Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 13:22
von Deluxe0321
Code: Alles auswählen
Interface __interface
SayHello(Text.s)
AddListElements(Count.i)
AddArrayElements(Count.i)
GetListSuff()
GetArrayStuff()
GetListElement()
SetListElement(Element.i)
GetArrayElement()
SetArrayElement(Element.i)
FreeAll()
EndInterface
Structure __listStruc
A.i
B.i
C.i
EndStructure
Structure __arrayStruc
Text.s
int.i
EndStructure
Structure __interfaceStruc
___procs.i
__MyListElement.i
__MyArrayElement.i
List MyList.__listStruc()
Array MyArray.__arrayStruc(0)
EndStructure
Procedure _SayHello(*this.__interfaceStruc,Text.s)
If Text.s
MessageRequester("Hello",Text.s)
EndIf
EndProcedure
Procedure _AddListElements(*this.__interfaceStruc,Count.i)
If Count.i > 0
For a=0 To Count.i
AddElement(*this\MyList())
*this\MyList()\A.i = Random(9999)
*this\MyList()\B.i = Random(9999)
*this\MyList()\C.i = Random(9999)
Next
ProcedureReturn Count.i
EndIf
ProcedureReturn -1
EndProcedure
Procedure _AddArrayElements(*this.__interfaceStruc,Count.i)
If Count.i > 0
ReDim *this\MyArray(Count.i)
For a=0 To Count.i
For b=0 To Count.i
*this\MyArray(a)\Text.s + Chr(65+Random(30))
Next
*this\MyArray(a)\int.i = Random(9999)
Next
ProcedureReturn Count.i
EndIf
ProcedureReturn -1
EndProcedure
Procedure _GetListSuff(*this.__interfaceStruc)
Static *MyListStatic.__listStruc
If ListSize(*this\MyList())
ResetList(*this\MyList())
SelectElement(*this\MyList(),*this\__MyListElement.i)
*MyListStatic = *this\MyList()
ProcedureReturn *MyListStatic
EndIf
EndProcedure
Procedure _GetArrayStuff(*this.__interfaceStruc)
Static *MyArrayStatic.__arrayStruc
If ArraySize(*this\MyArray())
*MyArrayStatic = *this\MyArray(*this\__MyArrayElement.i)
ProcedureReturn *MyArrayStatic
EndIf
EndProcedure
Procedure _GetListElement(*this.__interfaceStruc)
ProcedureReturn *this\__MyListElement.i
EndProcedure
Procedure _SetListElement(*this.__interfaceStruc,Element.i)
If Element.i > -1 And Element.i < ListSize(*this\MyList())
*this\__MyListElement.i = Element.i
ProcedureReturn #True
EndIf
EndProcedure
Procedure _GetArrayElement(*this.__interfaceStruc)
ProcedureReturn *this\__MyArrayElement.i
EndProcedure
Procedure _SetArrayElement(*this.__interfaceStruc,Element.i)
If Element.i > -1 And Element.i < ArraySize(*this\MyArray())
*this\__MyArrayElement.i = Element.i
ProcedureReturn #True
EndIf
EndProcedure
Procedure _FreeAll(*this.__interfaceStruc)
If ListSize(*this\MyList())
ClearList(*this\MyList())
EndIf
If ArraySize(*this\MyArray())
ReDim *this\MyArray(0)
EndIf
EndProcedure
Procedure NewMyInterface()
Protected *this.__interfaceStruc
*this = AllocateMemory(SizeOf(__interfaceStruc))
If *this
InitializeStructure(*this, __interfaceStruc)
*this\__MyArrayElement = -1
*this\__MyListElement = -1
*this\___procs.i = ?_interface_procs_
EndIf
ProcedureReturn *this
EndProcedure
DataSection
_interface_procs_:
Data.i @_SayHello()
Data.i @_AddListElements()
Data.i @_AddArrayElements()
Data.i @_GetListSuff()
Data.i @_GetArrayStuff()
Data.i @_GetListElement()
Data.i @_SetListElement()
Data.i @_GetArrayElement()
Data.i @_SetArrayElement()
Data.i @_FreeAll()
EndDataSection
;Create 3 "Structured Interfaces"
NewList *this.__interface()
For a=0 To 3
AddElement(*this())
*this() = NewMyInterface()
Next
;We want one element for now
SelectElement(*this(),1)
*myList.__listStruc
*myArray.__arrayStruc
*this()\SayHello("I like Turtels!")
;generate some Elements
*this()\AddArrayElements(100)
*this()\AddListElements(100)
For a=0 To 3
Debug a
;set the Element
*this()\SetListElement(Random(100))
;get the stuff
*myList = *this()\GetListSuff()
Debug *myList\A.i
Debug *myList\B.i
Debug *myList\C.i
Debug ""
Next
;set the Element
For a=0 To 3
*this()\SetArrayElement(Random(100))
;get the stuff
*myArray = *this()\GetArrayStuff()
Debug *myArray\int.i
Debug *myArray\Text.s
Debug ""
Next
*this()\FreeAll()
KP, ob das dein Problem löst, ich verstehe dich nicht ganz.

Intern kannst du erstellen, kopieren, löschen wie du lustig bist. Trotzdem musst du Angeben mit was gearbeitet werden soll.
Wenn du für Jedes Element deiner "Struktur" ein eigenes Inferface willst, ist das auch kein wirkliches Thema. Einfach erstellen.
Gruß Deluxe0321
Edit: Zu langsam

Gut das du eine Lösung für dich gefunden hast.
Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 14:01
von bobobo
aber schlecht dass die hier nicht gepostet worden ist 
Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 14:56
von delikanli_19_82
ich habe hier eine lösung gebastelt. bin damit aber nicht ganz zu frieden. eigentlich möchte ich die
struktur mit der linkedlist nicht global deklarieren, sondern in den objekt hineinpacken, so dass es von außen
nicht mehr zugänglich ist und nicht manipuliert werden kann.
Code: Alles auswählen
Structure capi_array_string_struct
List lst.s()
EndStructure
Global NewList capi_array_string_data.capi_array_string_struct()
Global capi_array_string_pointer.l = 0
Interface capi_array_string
Add( value.s )
Index.l( value.l = -1 )
Count.l()
Delete( value.l = 0 )
Value.s( value.l )
Clear()
EndInterface
Structure capi_array_string_body
Tbl.l
Met.l[SizeOf(capi_array_string)/4]
cnt.l
ptr.l
*lst.capi_array_string_struct
EndStructure
Procedure capi_array_string__Add( *this.capi_array_string_body, value.s )
AddElement( *this\lst\lst() )
*this\lst\lst() = value
*this\cnt + 1
EndProcedure
Procedure.l capi_array_string__Index( *this.capi_array_string_body, value.l = -1 )
If value >= 0 And value < *this\cnt
SelectElement( *this\lst\lst(), value )
EndIf
EndProcedure
Procedure.l capi_array_string__Count( *this.capi_array_string_body )
ProcedureReturn *this\cnt
EndProcedure
Procedure.l capi_array_string__Delete( *this.capi_array_string_body, value.l = 0 )
If value >= 0 And value < *this\cnt
DeleteElement( *this\lst\lst(), value )
EndIf
EndProcedure
Procedure.s capi_array_string__Value( *this.capi_array_string_body, value.l )
If value >= 0 And value < *this\cnt
SelectElement( *this\lst\lst(), value )
; ***
ProcedureReturn *this\lst\lst()
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure capi_array_string__Clear( *this.capi_array_string_body )
ClearList( *this\lst\lst() )
; ***
*this\cnt = 0
EndProcedure
Procedure capi_array_string ()
*obj.capi_array_string_body = AllocateMemory(SizeOf(capi_array_string_body))
If *obj = 0: ProcedureReturn 0 : EndIf ; Memory allocation failed
*obj\Tbl = *obj + OffsetOf(capi_array_string_body\Met)
; ***
*obj\cnt = 0
; ***
AddElement( capi_array_string_data() )
; ***
*obj\lst = capi_array_string_data()
; ***
capi_array_string_pointer + 1
; ***
*obj\Met[0] = @capi_array_string__Add()
*obj\Met[1] = @capi_array_string__Index()
*obj\Met[2] = @capi_array_string__Count()
*obj\Met[3] = @capi_array_string__Delete()
*obj\Met[4] = @capi_array_string__Value()
*obj\Met[5] = @capi_array_string__Clear()
; ***
ProcedureReturn *obj
EndProcedure
test.capi_array_string = capi_array_string()
test\Add( "Hallo" )
test\Add( "Welt" )
test\Add( "Ola" )
test\Add( "Ninja" )
Debug "TEST"
For x = 0 To test\Count() -1
Debug test\Value(x)
Next
Debug ""
zwei.capi_array_string = capi_array_string()
zwei\Add( "abc" )
zwei\Add( "def" )
Debug "ZWEI"
For x = 0 To zwei\Count() -1
Debug zwei\Value(x)
Next
ich habe versucht mit einer statischen strukturdeklaration innerhabl des constructors das problem zu lösen.
der hat aber den nachteil, das jede instanz, ja logischerweise, die selbe speicherstelle als interne liste
übernehmen. und das macht ja keinen sinn.
weiß jemand einen Rat?
mfg
kurt
Re: CopyStructure und LinkedLists
Verfasst: 25.05.2011 21:41
von NicTheQuick
Re: CopyStructure und LinkedLists
Verfasst: 26.05.2011 04:04
von delikanli_19_82
hier eine endgültige version für strings. dieser funktioniert jetzt perfekt. nochmals danke an alle beteiligten. habe nun daraus
noch varianten für long, integer, byte, float, double, word und unicode erstellt.
Code: Alles auswählen
; ------------------------------------------------------------------------------------------- ;
;
; Class Interface
;
; ------------------------------------------------------------------------------------------- ;
Interface capi_array_string
Add( value.s )
Index.l( value.l = -1 )
Count.l()
Delete( value.l = 0 )
; Das {...} dient als Default, um damit einen ProcedureReturn, statt Manipulation zu bewirken
Value.s( index.l, value.s = "{ABCDE-EFC32-32321-0323EC-32DEC-123EF}" )
Clear()
Sort( nocase.b = #False, increment.b = #True )
Find.b( value.s, nocase.b = #False )
Where.l( value.s, nocase.b = #False )
Min.s()
Max.s()
Filter( value.s, nocase.b = #False )
EndInterface
; ------------------------------------------------------------------------------------------- ;
;
; Class Body Structure
;
; ------------------------------------------------------------------------------------------- ;
Structure capi_array_string_body
Met.i
cnt.l
List lst.s()
EndStructure
; ------------------------------------------------------------------------------------------- ;
;
; Add value
;
; ------------------------------------------------------------------------------------------- ;
Procedure capi_array_string_Add( *this.capi_array_string_body, value.s )
If *this\cnt > 0
LastElement( *this\lst() )
EndIf
; ***
AddElement( *this\lst() )
; ***
*this\lst() = value
; ***
*this\cnt + 1
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Return or set index
;
; ------------------------------------------------------------------------------------------- ;
Procedure.l capi_array_string_Index( *this.capi_array_string_body, index.l = -1 )
If index = -1
ProcedureReturn ListIndex( *this\lst() )
ElseIf index >= 0 And index < *this\cnt
SelectElement( *this\lst(), index )
EndIf
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Return count of entries
;
; ------------------------------------------------------------------------------------------- ;
Procedure.l capi_array_string_Count( *this.capi_array_string_body )
ProcedureReturn *this\cnt
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Delete an entry
;
; ------------------------------------------------------------------------------------------- ;
Procedure.l capi_array_string_Delete( *this.capi_array_string_body, index.l = 0 )
If index >= 0 And index < *this\cnt
SelectElement( *this\lst(), index )
; ***
DeleteElement( *this\lst() )
; ***
*this\cnt - 1
; ***
If *this\cnt > 0
LastElement( *this\lst() )
EndIf
EndIf
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Return or modify the value
;
; ------------------------------------------------------------------------------------------- ;
Procedure.s capi_array_string_Value( *this.capi_array_string_body, index.l, value.s = "{ABCDE-EFC32-32321-0323EC-32DEC-123EF}" )
If index >= 0 And index < *this\cnt
SelectElement( *this\lst(), index )
; ***
If value = "{ABCDE-EFC32-32321-0323EC-32DEC-123EF}"
ProcedureReturn *this\lst()
Else
*this\lst() = value
EndIf
Else
ProcedureReturn ""
EndIf
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Clear array
;
; ------------------------------------------------------------------------------------------- ;
Procedure capi_array_string_Clear( *this.capi_array_string_body )
If *this\cnt > 0
ClearList( *this\lst() )
; ***
*this\cnt = 0
EndIf
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Sort array
;
; ------------------------------------------------------------------------------------------- ;
Procedure capi_array_string_Sort( *this.capi_array_string_body, nocase.b = #False, increment.b = #True )
If *this\cnt > 0
If nocase = #False
If increment = #True
SortList( *this\lst(), #PB_Sort_Ascending | #PB_Sort_NoCase )
Else
SortList( *this\lst(), #PB_Sort_Descending | #PB_Sort_NoCase )
EndIf
Else
If increment = #True
SortList( *this\lst(), #PB_Sort_Ascending )
Else
SortList( *this\lst(), #PB_Sort_Descending )
EndIf
EndIf
LastElement( *this\lst() )
EndIf
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Find a value. If found, return #true, otherwise #false.
;
; ------------------------------------------------------------------------------------------- ;
Procedure.b capi_array_string_Find( *this.capi_array_string_body, value.s, nocase.b = #False )
Define bool.b = #False, v.s
If *this\cnt > 0
ForEach *this\lst()
v = *this\lst()
If v = value And nocase = #False
bool = #True
Break
ElseIf v = value And nocase = #True
bool = #True
Break
ElseIf LCase(v) = LCase(value) And nocase = #True
bool = #True
Break
EndIf
Next
LastElement( *this\lst() )
EndIf
ProcedureReturn bool
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Return the index of a found value, otherwise -1.
;
; ------------------------------------------------------------------------------------------- ;
Procedure.l capi_array_string_Where( *this.capi_array_string_body, value.s, nocase.b = #False )
Define pos.l = -1, v.s
If *this\cnt > 0
ForEach *this\lst()
v = *this\lst()
pos + 1
If v = value And nocase = #False
Break
ElseIf v = value And nocase = #True
Break
ElseIf LCase(v) = LCase(value) And nocase = #True
Break
EndIf
Next
LastElement( *this\lst() )
EndIf
ProcedureReturn pos
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Return the smallest value
;
; ------------------------------------------------------------------------------------------- ;
Procedure.s capi_array_string_Min( *this.capi_array_string_body )
Define v.s, t.s, c.l = 32000
If *this\cnt > 0
ForEach *this\lst()
v = *this\lst()
If Len(v) < c : c = Len(v) : t = v : EndIf
Next
LastElement( *this\lst() )
EndIf
ProcedureReturn t
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Return the largest value
;
; ------------------------------------------------------------------------------------------- ;
Procedure.s capi_array_string_Max( *this.capi_array_string_body )
Define v.s, t.s, c.l = 0
If *this\cnt > 0
ForEach *this\lst()
v = *this\lst()
If Len(v) > c : c = Len(v) : t = v : EndIf
Next
LastElement( *this\lst() )
EndIf
ProcedureReturn t
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Filter values from the list
;
; ------------------------------------------------------------------------------------------- ;
Procedure capi_array_string_Filter( *this.capi_array_string_body, value.s, nocase.b = #False )
Define v.s
If *this\cnt > 0
ForEach *this\lst()
v = *this\lst()
If v = value And nocase = #False
DeleteElement( *this\lst() ) : *this\cnt - 1
ElseIf v = value And nocase = #True
DeleteElement( *this\lst() ) : *this\cnt - 1
ElseIf LCase(v) = LCase(value) And nocase = #True
DeleteElement( *this\lst() ) : *this\cnt - 1
EndIf
Next
If *this\cnt > 0 : LastElement( *this\lst() ) : EndIf
EndIf
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Class Construtor
;
; ------------------------------------------------------------------------------------------- ;
Procedure capi_array_string()
Protected *this.capi_array_string_body
*this = AllocateMemory(SizeOf(capi_array_string_body))
If *this
InitializeStructure(*this, capi_array_string_body)
*this\cnt = 0
*this\Met.i = ?_capi_array_string_procs_
EndIf
ProcedureReturn *this
EndProcedure
; ------------------------------------------------------------------------------------------- ;
;
; Class Methods
;
; ------------------------------------------------------------------------------------------- ;
DataSection
_capi_array_string_procs_:
Data.i @capi_array_string_Add()
Data.i @capi_array_string_Index()
Data.i @capi_array_string_Count()
Data.i @capi_array_string_Delete()
Data.i @capi_array_string_Value()
Data.i @capi_array_string_Clear()
Data.i @capi_array_string_Sort()
Data.i @capi_array_string_Find()
Data.i @capi_array_string_Where()
Data.i @capi_array_string_Min()
Data.i @capi_array_string_Max()
Data.i @capi_array_string_Filter()
EndDataSection
und hier ein test:
Code: Alles auswählen
test.capi_array_string = capi_array_string()
test\Add( "Aachen" )
test\Add( "Köln" )
test\Add( "Düsseldorf" )
test\Add( "Münster" )
For x = 0 to test\Count() - 1
Debug Test\Value(x)
Next
test\Sort( #True, #False )
Debug ""
For x = 0 to test\Count() - 1
Debug Test\Value(x)
Next
Debug ""
Debug test\Min()
Debug test\Max()
Debug test\Count()
test\Clear()
Debug ""
Debug "Tada... :-)"
Re: CopyStructure und LinkedLists
Verfasst: 26.05.2011 10:52
von NicTheQuick
Min und Max könntest du optimieren, indem du die beiden Werte schon beim Hinzufügen (add()) aktualisierst und beim Abfragen einfach nur zurück gibst.
Desweiteren finde ich deine Definition von Min und Max für Strings merkwürdig. Ich verstehe darunter zumindest nicht die String-Länge.