Changes to an array inside a function don't carry over

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Punpun
:warning: Old Version Published before Godot 3 was released.

Hi guys, i’m trying to make my godot project compatible with my old server.
The way data should be sent is: (packet.size, data1, data1.end, data2, data2.end), being paket.size, data_count.end obligatory in pure hex, and data_count in utf8_string, wich I got over with RawArrays.

However, in the future i’ll need to send other types of data, like decimals, so I tried to write a function that would do it for me in a way that I wouldn’t have to write long strings of data in arrays. I tried doing the strings first:

#writes str packet
func pkt_write_str(array, data):
    array.append_array(data.to_utf8()) #writes bytes in the array
    array.append(0)                    #data_count.end


#format and send packet
func pkt_send(array):	
	array.insert(0, array.size()+1)    #+1 for the actual byte that
    client.put_data(array)             #packet.size takes


#sends packet on button release
func _on_Button_released():
	var login = "login"
	var user = get_node("log_strut/username").get_text()
	var pasw = get_node("log_strut/password").get_text()

    var loginpkt = RawArray([])
    pkt_write_str(loginpkt,login)
	pkt_write_str(loginpkt,user)
	pkt_write_str(loginpkt,pasw)
	pkt_send(loginpkt)
            

As it turns out, the function didn’t write a byte to the array. Well, it did,
but it did not carry over to the next circle, neither to the next function.
Am I forgetting something? Is a work around possible in this case?

:bust_in_silhouette: Reply From: Zylann

My guess is that RawArray is a value type, not a reference type. So when you modify it in a function, you are actually modifying a local copy (or maybe it works with Copy-On-Write mode?)
If you don’t want to use the built-in functions of StreamPeer, you could use a normal array, then convert it to RawArray at the very end.

I would use a normal array, but everytime i try to convert an array
with a string to a RawArray it ends up as a single null byte on the server.

But what you said about modifying a local copy really fits, printing the result
inside the first function shows that the string is being properly written, it
just seems to reset at the end of the cicle, it won’t add up to the last change.
Is there around it?

Punpun | 2016-10-21 10:12

Just do what you do, but with a normal array. But at the end, iterate that array, get the type of every element and serialize the item the way you want:

for item in arr:
    type = typeof(item)
    if type == TYPE_STRING:
        rawarray.put....
    elif type == TYPE_INT:
        rawarray.put... etc
    ...

This way you will bypass the fact RawArray doesn’t carry out changes because you can do all this in the same scope.

But I’m still curious why RawArray works like that tbh.

Zylann | 2016-10-21 15:58

What I did:

#create place holder
s_packet = RawArray([]) #must be raw array to hold data in utf8 


#iterate
func pkt_write_tst(array):
	for data in array:
		var type = typeof(data)
		if type == TYPE_STRING:
			s_packet.append_array(data.to_utf8())
			s_packet.append(0)

		elif type == TYPE_INT:
			s_packet.append_array(data.to_utf8())
			s_packet.append(0)
#sends packet on button release
func _on_login_released():
	var login = "login"
	var user = get_node("log_strut/username").get_text()
	var pasw = get_node("log_strut/password").get_text()

	var loginpkt = Array([login,user,pasw])
	pkt_write_tst(loginpkt)

And I got pretty much the same result, the final array didn’t carry over. At this point I’m ok doing it the long way, I just want to know why functions can’t write off their scope, and why there ins’t a work around it.

Punpun | 2016-10-21 17:59

Instead

...
    #iterate
    func pkt_write_tst(array):
        for data in array:
            var type = typeof(data)
...

Try

...
    #iterate
    func pkt_write_tst(array):
        for i in range(array.size()):
            var type = typeof(array(i))
...

Carrot_in | 2017-07-14 12:49