Sowas brauche ich damit nicht jedes mal eine neue Struktur erzeugt wird.
Vieleicht geht sowas auch schon und ich weiß es noch nicht.
FUNCTION >>>ByRef<<< FindPlayer AS TPlayer:Nr
FOREACH P IN Players[]
IF P.Nr=Nr THEN RETURN P
NEXT
ENDFUNCTION
Tatsache ist das ich hier den echten Inhalt vom Array bekomme
LOCAL P AS TPlayer
FOREACH P IN Players[]
P.Draw()
IF P.Nr=1 THEN P.Update() //das geht
NEXT
Plan B geht nicht (das Byref ist bei PR wohl schon automatisch bei)
FUNCTION FindPlayer:Nr, PR AS TPlayer
FOREACH PR IN Players[]
IF PR.Nr=Nr
BREAK
ENDIF
NEXT
ENDFUNCTION
Sowas macht eine Kopie
FUNCTION FindPlayer:Nr, PR AS TPlayer
FOREACH P IN Players[]
IF P.Nr=Nr
PR=P
BREAK
ENDIF
NEXT
ENDFUNCTION
Geht nicht
FUNCTION FindPlayer: Nr, BYREF p AS TPlayer
FOREACH P IN Players[]
IF P.Nr=Nr THEN p = P
NEXT
ENDFUNCTION
?
Meinst du sowas, dass die Funktion den Typen zurückliefert? Doch das geht schon. musst nur die Funktion entsprechend deklarieren:
TYPE TPlayer
text$
ENDTYPE
GLOBAL players[] AS TPlayer
DIM players[3]
players[0].text$ = "Erster"
players[1].text$ = "Zweiter"
players[2].text$ = "Dritter"
LOCAL test AS TPlayer
test = get_player("Zweiter")
STDOUT test.text$
KEYWAIT
FUNCTION get_player AS TPlayer: text$
FOREACH p IN players[]
IF p.text$ = text$
RETURN p
ENDIF
NEXT
ENDFUNCTION
Dein Beispiel hat er doch als erste Funktion genannt, nur das er da irgendwie nen BYREF haben will. :P
Byref geht nicht. Aber Du kannst ja byref als argument übergeben.
Wenn Du BYREF returnen willst - worauf soll der Rückgabewert zeigen!?
QuoteByref geht nicht. Aber Du kannst ja byref als argument übergeben.
Damit meinst Du doch meine Idee, oder nicht?
ja. genau.
...warum red ich überhaupt...
byref bei einem Parameter mit Struktur gibt mir ein Syntax Error.
ich gehe aber davon aus das der Parameter eh schon als Pointer übergeben wird weil das nur ein paar Bytes sind und so üblich ist.
Oben mein Beispiel ging aber nicht wie ich das erwartet hatte.
Bei A=B habt ihr mir erklärt das dort die Struktur B nach A kopiert wird,ich will aber B haben original :-)
@Quentin
ich möchte keine kopie als Rückgabe
@Kitty Hello
ich will quasi Pointer tauschen bzw. weiter geben und Variable A durch B ersetzen vom gleichem Typ.
Das was im Array ist möchte ich mit einer Funktion raus suchen ohne eine kopie zu erstellen, dann mit .MachIrgendwas() ändern.
Ansonsten muß ich bei einer Kopie das ja auch wieder zurück kopieren in mein Array.
Und wenn man mit kopien arbeitet dann haben andere Funktionen wieder nicht das aktuelle.
Kopien kosten zu dem unnötig Zeit.
Was zum experimentieren:
TYPE TPlayer
Nr
Name$
x
y
Money
FUNCTION Draw:
SETPIXEL self.x,self.y,RGB(255,255,255)
ENDFUNCTION
FUNCTION Position: x,y
self.x=x
self.y=y
ENDFUNCTION
FUNCTION Update:
//<- 203 Cursors
//-> 205
//^ 200
//V 208
//o 28 RETURN
LOCAL Name$=self.Name$ //for debug
IF KEY(205)
IF self.x<800 THEN self.x=self.x+1
ENDIF
ENDFUNCTION
ENDTYPE
GLOBAL Players[] AS TPlayer
ALLOWESCAPE TRUE
MainLoop()
END
FUNCTION MainLoop:
LOCAL A AS TPlayer
A.Nr=1
A.Name$="Markus"
A.Position(100,300)
LOCAL B AS TPlayer
B.Nr=2
B.Name$="Computer"
B.Position(800-100,300)
DIMPUSH Players[],A
DIMPUSH Players[],B
REPEAT
LOCAL P AS TPlayer
FOREACH P IN Players[]
P.Draw()
//IF P.Nr=1 THEN P.Update() //das geht
NEXT
FindPlayer(1,P)
P.Update() //das nicht weil das wohl eine Kopie der Struktur ist
//ReplacePlayer(1,P) //Workaround
SHOWSCREEN
UNTIL FALSE
ENDFUNCTION
// P als BYREF gibt Syntax Error
FUNCTION FindPlayer: Nr, P AS TPlayer
FOREACH P IN Players[]
IF P.Nr=Nr
BREAK
ENDIF
NEXT
ENDFUNCTION
Keine Chance. Das Array ist ein echtes Array, keine Liste mit Pointern. Was in's Array soll, muss reinkopiert werden.
Bevor jetzt das Geheule über Geschwindigkeit losgeht, bitte erst ein konkretes Projekt machen und prüfen ob's wirklich "langsam" ist. Die GLB Arrays sind nämlich oft viel schneller als so linked-list Kram.
@Kitty Hello
Ich will doch direkt im Array arbeiten und hier mit dem Beispiel geht es ja auch.
Dieses P ist doch ein Block der im Speicher (Array) steht, den möchte ich auch bearbeiten.
Ich bekomme aber das P nicht aus einer Funktion zurück ohne das es als Kopie angelegt wird.
Wie ich das verstehe ist das P in dem Beispiel unten ein Pointer auf einen Speicherbereich wo die Struktur in echt ist oder ?
Wenn ich bei Update() mit self.xy=x einen Wert zuweise ist das wieder im Array darum gehe ich davon aus das P ein Ausschnitt vom Array ist.
LOCAL P AS TPlayer
FOREACH P IN Players[]
P.Draw()
IF P.Nr=1 THEN P.Update() //das geht
NEXT
INLINE :enc:
Quote from: Markus on 2012-Apr-24
@Quentin
ich möchte keine kopie als Rückgabe
ja sorry, hatte ich übersehen, hattest du ja schon probiert.
Was dein "P" hier angeht:
lt. Hilfe
"Man muss "ref" nicht als LOCAL definieren. Das passiert automatisch. Jedoch ist "ref" nach dem zugehörigem "NEXT" nicht mehr gültig."
Das beantwortet wohl, warum du nach der FOREACH-Schleife nicht mehr auf dein P zugreifen kannst. Und wenn du unbedingt direkt mit dem Array arbeiten willst, ohne irgendwelche Kopieraktionen, wieso arbeitest du dann nicht mit einem Index.
Anstatt FOREACH einfache FOR-Schleife:
FOR i = 0 TO LEN(Players[]) - 1
Players[i].draw()
NEXT
// damit kannst du dann auch außerhalb der Schleife gezielt über den Index zugreifen
// und deine gezeigte FindPlayer-Funktion wäre überflüssig
Players[5].update()
Quote from: Quentin on 2012-Apr-24
Und wenn du unbedingt direkt mit dem Array arbeiten willst, ohne irgendwelche Kopieraktionen, wieso arbeitest du dann nicht mit einem Index.
Richtig, mach es nach dem GLB-Way, oder nutze einfach INLINE...
Ist ja das coole an GLB das du mixen kannst :)
@Quentin
ich wollte auch nicht nach der Schleife das P noch benutzen.
Das sieht jetzt nur in dem Beispiel so aus weil ich Experimente mache.
In der Funktion das P nach Außen geben .
Ich habe aber Explizite Deklaration an,warum nacht dann das ForEach
selber was ? Aber ich sehe grad dank dir wie das ForEach gemacht ist.
Da wird tatsächlich am Anfang und Ende alles kopiert, das muß ich ja dann
wohl auch so machen :-)
@Schranz0r
ihr habt mich grad auf die Idee gebracht das Array als Byref zu übergeben :-)
@Kitty Hello
hab dank Quentin ein Beispiel gefunden was das ForEach eigentlich macht.
Also.
Einen Zeiger auf ein Element bekommst Du mit:
ALIAS zeiger AS feld[index]
zeiger.xx
Oder Du übergibst an eine Funktion. Types werden _immer_ BYREF übergeben. Arrays auch.
@Kitty Hello :enc:
danke, spiele ich mal mit rum ;)
Wenn wie in der Hilfe dieses Each
Quote
FOREACH ref IN feld[]
...
NEXT
echt wie sowas ist
Quote
FOR i = 0 to BOUNDS(feld[],0)-1
ref = feld
...
feld = ref
NEXT
dann wäre nach Adam Riese ref schon eine Kopie.
Jede Sprache macht es anders , das Beispiel in der Hilfe war nützlich.
(mit "Objekten" die immer Byref übergeben werden kenne ich von MS,fände es aber logischer wenn es davor stehen würde weil die anderen wohl byval sind oder.)
:x
@Alle
Danke
Und falls das jemand interessiert :booze:
TYPE TPlayer
Nr
Name$
x
y
Money
FUNCTION Draw:
SETPIXEL self.x,self.y,RGB(255,255,255)
ENDFUNCTION
FUNCTION Position: x,y
self.x=x
self.y=y
ENDFUNCTION
FUNCTION Update:
//<- 203 Cursors
//-> 205
//^ 200
//V 208
//o 28 RETURN
LOCAL Name$=self.Name$ //for debug
IF KEY(205) // Taste nach rechts
IF self.x<800 THEN self.x=self.x+1
ENDIF
ENDFUNCTION
ENDTYPE
GLOBAL Players[] AS TPlayer
ALLOWESCAPE TRUE
MainLoop()
END
FUNCTION MainLoop:
LOCAL A AS TPlayer
A.Nr=1
A.Name$="Markus"
A.Position(100,300)
LOCAL B AS TPlayer
B.Nr=2
B.Name$="Computer"
B.Position(800-100,300)
DIMPUSH Players[],A
DIMPUSH Players[],B
REPEAT
FOREACH P IN Players[]
P.Draw()
NEXT
LOCAL i%
i=FindPlayer(1,Players[])
ALIAS P AS Players[i] //so vereinfacht die Schreibweise enorm und man arbeitet mit dem Original
P.Update() // Fragt nur die Rechts Taste ab
SHOWSCREEN
UNTIL FALSE
ENDFUNCTION
FUNCTION FindPlayer: Nr,List[] AS TPlayer //damit innen keine Globalen Variablen benutzt werden die Liste als Byref
LOCAL i%
FOR i = 0 TO BOUNDS(List[],0)-1
IF List[i].Nr=Nr
RETURN i
BREAK
ENDIF
NEXT
RETURN 0
ENDFUNCTION
FOREACH j IN ar[] ist sowas wie:
FOR I%= 0 to LEN(ar[])-1
ALIAS j AS as
j...
NEXT
@Kitty Hello
viel anders weiter geben konnte ich die Variable mit dem Alias nicht
aber das Alias hilft sehr damit es übersichtlicher bleibt.
Habe jetzt den dreh raus.