В чём причина зависания кода?
Начал писать чекер 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