red-blox / zap

A lightning fast networking solution for roblox.
https://zap.redblox.dev
MIT License
89 stars 14 forks source link

Fix nested arrays #96

Closed Ketasaja closed 2 months ago

Ketasaja commented 2 months ago

Allows for types like this:

event test = {
    from: Client,
    type: Reliable,
    call: ManyAsync,
    data: u8[10][20][2][2],
}

Clearly the generated code should be cleaner, i_v_i_v_v_i_v_i_v_v_v_i_v_i_v_v_i_v_i_v_v_v_v is absolutely not an acceptable variable name long-term, this is only meant as a temporary fix.

Before (i shadowing breaks code):

local returns = {
    test = {
        fire = function(value: ({ ({ ({ ({ (number) }) }) }) }))
            alloc(1)
            buffer.writeu8(outgoing_buff, outgoing_apos, 1)
            assert(#value == 2)
            for i = 1, 2 do
                assert(#value[i] == 2)
                for i = 1, 2 do
                    assert(#value[i][i] == 20)
                    for i = 1, 20 do
                        assert(#value[i][i][i] == 10)
                        for i = 1, 10 do
                            alloc(1)
                            buffer.writeu8(outgoing_buff, outgoing_apos, value[i][i][i][i])
                        end
                    end
                end
            end
        end,
    },
}

After:

local returns = {
    test = {
        fire = function(value: ({ ({ ({ ({ (number) }) }) }) }))
            alloc(1)
            buffer.writeu8(outgoing_buff, outgoing_apos, 1)
            assert(#value == 2)
            for i_v = 1, 2 do
                assert(#value[i_v] == 2)
                for i_v_i_v_v = 1, 2 do
                    assert(#value[i_v][i_v_i_v_v] == 20)
                    for i_v_i_v_v_i_v_i_v_v_v = 1, 20 do
                        assert(#value[i_v][i_v_i_v_v][i_v_i_v_v_i_v_i_v_v_v] == 10)
                        for i_v_i_v_v_i_v_i_v_v_v_i_v_i_v_v_i_v_i_v_v_v_v = 1, 10 do
                            alloc(1)
                            buffer.writeu8(outgoing_buff, outgoing_apos, value[i_v][i_v_i_v_v][i_v_i_v_v_i_v_i_v_v_v][i_v_i_v_v_i_v_i_v_v_v_i_v_i_v_v_i_v_i_v_v_v_v])
                        end
                    end
                end
            end
        end,
    },
}
sasial-dev commented 2 months ago

Maybe we need to update into.display_escaped() to not produce something like i_v_i_v_v_i_v_i_v_v_v_i_v_i_v_v_i_v_i_v_v_v_v. It's a bit stupid, and display_escaped is a simple function. Let me know your thoughts.

Ketasaja commented 2 months ago

Arrays:

event test = {
    from: Client,
    type: Reliable,
    call: ManyAsync,
    data: u8[10][20][2][2],
}
if id == 1 then
    local value
    value = {}
    for i_1 = 1, 2 do
        value[i_1] = {}
        for i_2 = 1, 2 do
            value[i_1][i_2] = {}
            for i_3 = 1, 20 do
                value[i_1][i_2][i_3] = {}
                for i_4 = 1, 10 do
                    value[i_1][i_2][i_3][i_4] = buffer.readu8(incoming_buff, read(1))
                end
            end
        end
    end
    for _, cb in events[1] do
        task.spawn(cb, player, value)
    end
else
    error("Unknown event id")
end

Maps:

event test = {
    from: Client,
    type: Reliable,
    call: ManyAsync,
    data: map { [
        map { [string]: boolean }
    ]:
        map {
            [boolean]:
            string[][][]
        }
    }[]
}
if id == 1 then
    local value
    value = {}
    local len = buffer.readu16(incoming_buff, read(2))
    for i_1 = 1, len do
        local j_1
        j_1 = {}
        for _ = 1, buffer.readu16(incoming_buff, read(2)) do
            local key_3
            local val_3
            key_3 = {}
            for _ = 1, buffer.readu16(incoming_buff, read(2)) do
                local key_5
                local val_5
                local len = buffer.readu16(incoming_buff, read(2))
                key_5 = buffer.readstring(incoming_buff, read(len), len)
                val_5 = buffer.readu8(incoming_buff, read(1)) == 1
                key_3[key_5] = val_5
            end
            val_3 = {}
            for _ = 1, buffer.readu16(incoming_buff, read(2)) do
                local key_5
                local val_5
                key_5 = buffer.readu8(incoming_buff, read(1)) == 1
                val_5 = {}
                local len = buffer.readu16(incoming_buff, read(2))
                for i_7 = 1, len do
                    local j_7
                    j_7 = {}
                    local len = buffer.readu16(incoming_buff, read(2))
                    for i_9 = 1, len do
                        local j_9
                        j_9 = {}
                        local len = buffer.readu16(incoming_buff, read(2))
                        for i_11 = 1, len do
                            local j_11
                            local len = buffer.readu16(incoming_buff, read(2))
                            j_11 = buffer.readstring(incoming_buff, read(len), len)
                            j_9[i_11] = j_11
                        end
                        j_7[i_9] = j_9
                    end
                    val_5[i_7] = j_7
                end
                val_3[key_5] = val_5
            end
            j_1[key_3] = val_3
        end
        value[i_1] = j_1
    end
    for _, cb in events[1] do
        task.spawn(cb, player, value)
    end
else
    error("Unknown event id")
end
sasial-dev commented 2 months ago

That's much better.