В чём причина зависания кода?

Начал писать чекер json свойств (тк в движке нельзя добавлять кастомные библиотеки) и столкнулся с проблемой, что движок зависает. Проблема в коде, тк зависает именно тогда, когда у блока отсутсвует свойство. Движок - https://github.com/MihailRis/VoxelEngine-Cpp Логи:

base:blocks/grass_block.json
nil
nil

Код чекера:

function read(blockid, property)
    blockid = block.name(blockid)
    local separator = ":"

    local separator_index = string.find(blockid, separator)

    if separator_index then
        local contentid = string.sub(blockid, 1, separator_index - 1)
        local block = string.sub(blockid, separator_index + 1)

        if (contentid == "core") then
            return nil
        end

        path = contentid .. ":blocks/" .. block .. ".json"

        print(path)

        json_data = [[]]

        json_data = file.read(path)

        local value = nil
        local current_pos = 1
        local key, val = nil, nil

        while true do
            while json_data:sub(current_pos, current_pos):match("[%s:,{}]") do
                current_pos = current_pos + 1
            end
            if current_pos > #json_data then
                break
            end

            local start_pos = current_pos
            while json_data:sub(current_pos, current_pos) ~= ":" do
                current_pos = current_pos + 1
            end
            key = json_data:sub(start_pos, current_pos - 1)
            key = key:gsub('"', '')

            current_pos = current_pos + 1

            start_pos = current_pos
            while json_data:sub(current_pos, current_pos) ~= "," and json_data:sub(current_pos, current_pos) ~= "}" do
                current_pos = current_pos + 1
            end
            val = json_data:sub(start_pos, current_pos - 1)

            value = tonumber(val)
            print(value)

            if key == property then
                return value
            end
        end
        print(value)
        print("Returning nil")
        return nil
    else
        print("Failed to split the blockid.")
    end
end

Код блока:

require "rstr:reader"

function on_update(x, y, z)
    if (tonumber(read(block.get(x + 1, y, z), "is-enabled-energy")) == 3 or tonumber(read(block.get(x - 1, y, z), "is-enabled-energy")) == 3 or tonumber(read(block.get(x, y + 1, z), "is-enabled-energy")) == 3 or tonumber(read(block.get(x, y - 1, z), "is-enabled-energy")) == 3 or tonumber(read(block.get(x, y, z + 1), "is-enabled-energy")) == 3 or tonumber(read(block.get(x, y, z - 1), "is-enabled-energy")) == 3) then
        block.set(x, y, z, block.index("rstem:wire_weak_2"))
    end
    if (tonumber(read(block.get(x + 1, y, z), "is-enabled-energy")) == 2 or tonumber(read(block.get(x - 1, y, z), "is-enabled-energy")) == 2 or tonumber(read(block.get(x, y + 1, z), "is-enabled-energy")) == 2 or tonumber(read(block.get(x, y - 1, z), "is-enabled-energy")) == 2 or tonumber(read(block.get(x, y, z + 1), "is-enabled-energy")) == 2 or tonumber(read(block.get(x, y, z - 1), "is-enabled-energy")) == 2) then
        block.set(x, y, z, block.index("rstem:wire_weak_1"))
    end
    if (tonumber(read(block.get(x + 1, y, z), "is-enabled-energy")) > 3 and tonumber(read(block.get(x - 1, y, z), "is-enabled-energy")) > 3 and tonumber(read(block.get(x, y + 1, z), "is-enabled-energy")) > 3 and tonumber(read(block.get(x, y - 1, z), "is-enabled-energy")) > 3 and tonumber(read(block.get(x, y, z + 1), "is-enabled-energy")) > 3) then
        block.set(x, y, z, block.index("base:rust"))
    end
end

Ответы (1 шт):

Автор решения: rost

Причина была в бесконечном цикле, если он не может найти нужное свойство. Исправленный код:

function read(blockid, property)
    blockid = block.name(blockid)
    local separator = ":"

    local separator_index = string.find(blockid, separator)

    if separator_index then
        local contentid = string.sub(blockid, 1, separator_index - 1)
        local block = string.sub(blockid, separator_index + 1)

        if (contentid == "core") then
            return 0
        end

        path = contentid .. ":blocks/" .. block .. ".json"

        print(path)

        json_data = [[]]

        json_data = file.read(path)

        local value = nil
        local current_pos = 1
        local key, val = nil, nil
        local tryes = 0

        while true do
            local tryes3 = 0
            print("Finding for " .. path)
            while json_data:sub(current_pos, current_pos):match("[%s:,{}]") do
                current_pos = current_pos + 1
                if (tryes3 > 10000) then
                    return 0
                end
                tryes3 = tryes3 + 1
            end
            if current_pos > #json_data then
                break
            end

            local start_pos = current_pos
            local tryes2 = 0
            print("The second finding for " .. path)
            while json_data:sub(current_pos, current_pos) ~= ":" do
                current_pos = current_pos + 1
                if (tryes2 > 10000) then
                    return 0
                end
                tryes2 = tryes2 + 1
            end
            key = json_data:sub(start_pos, current_pos - 1)
            key = key:gsub('"', '')

            current_pos = current_pos + 1

            start_pos = current_pos
            print("Finalling finding for " .. path)
            while json_data:sub(current_pos, current_pos) ~= "," and json_data:sub(current_pos, current_pos) ~= "}" do
                current_pos = current_pos + 1
            end
            if current_pos > #json_data then
                print("Can't move!")
                break
            end
            if (key == property) then
                print("key == property true!")
            end
            val = json_data:sub(start_pos, current_pos - 1)
            value = tonumber(val)
            print(value)

            if key == property then
                return value
            end
            if (tryes > 10000) then
                return 0
            end
            tryes = tryes + 1
        end
        print(value)
        print("Returning nil")
        return value
    else
        print("Failed to split the blockid.")
    end
end
→ Ссылка