Сниппет LuaDeb: различия между версиями
Va (обсуждение | вклад) Нет описания правки |
Va (обсуждение | вклад) мНет описания правки |
||
| (не показана 1 промежуточная версия этого же участника) | |||
| Строка 25: | Строка 25: | ||
Привязка нескольких мониторов на один канал digiline дублирует информацию. Это может быть полезно для разнесения мониторов в удобные для наблюдения места или для использования двух разных типов мониторов. | Привязка нескольких мониторов на один канал digiline дублирует информацию. Это может быть полезно для разнесения мониторов в удобные для наблюдения места или для использования двух разных типов мониторов. | ||
Код, с примерами обработки. В данном случае порт А пустой, порт C подключён к {{Obj|mesecons_lamp|lamp_off|4=id}}, к какому-то порту, B или D датчик мезеконс-сигнала, например, {{Obj|mesecons_button|button_off|4=id}}, и к оставшемуся порту подключён тач-скрин с идентификатором ts1 и дисплей с идентификатором d1. | Код, с примерами обработки. В данном случае | ||
* порт А пустой, | |||
* порт C подключён к {{Obj|mesecons_lamp|lamp_off|4=id}}, | |||
* к какому-то порту, B или D, подключён датчик мезеконс-сигнала, например, {{Obj|mesecons_button|button_off|4=id}}, | |||
* и к оставшемуся порту подключён тач-скрин с идентификатором ts1 и дисплей с идентификатором d1. | |||
<pre> | <pre> | ||
| Строка 122: | Строка 126: | ||
function fB () | function fB () | ||
log("fB: in"); | log("fB: in"); | ||
port={a=false; | port={a=false;c=false}; | ||
log("fB: out"); | log("fB: out"); | ||
end | end | ||
Текущая версия от 19:20, 11 февраля 2025
Lua контроллер Mesecons при игре в серверном варианте не имеет даже самых простых средств отладки. Даже простой вывод функцией print не может быть получен на стороне игрока, потому что код контроллера выполняется на сервере игры. Остаётся только выводить отладочную информацию средствами, доступными в игре - digilines:lcd
, digiterms:lcd_monitor
, digistuff:touchscreen
. И все не очень удобно, всё имеет недостатки. Чтобы как-то решить проблему требуется логирование с буферизацией. Собственно, эту задачу и решает данный отладчик - предоставляет унифицированную структуру программы, функцию log() и возможность просмотра накопленных сообщений по запросу.
Полностью разделить код прикладной программы и отладчика вряд ли получится при текущей реализации системы Lua контроллер Mesecons. Поэтому прикладная часть просто вписывается в данный шаблон.
Унификация структуры сводится к трём функциям - fmain(), fintr(), fdigi(), которые дополняются прикладным кодом. Плюс механизм дополнения панели отладчика собственными кнопками управления.
Принципиальная схема отладчика:
![]() |
|||
![]() |
![]() |
||
![]() |
![]() |
![]() | |
![]() (ts1) |
![]() (d1) |
![]() (d1) |
Где ts1 и d1 - названия каналов/идентификаторов digiline, которые закреплены за отладчиком, и могут быть заменены через определение констант.
Прикладные датчики и исполнители подключаются к линиям digilines или msecons. Естественное ограничение - использование отладчика требует одного порта контроллера для подключения digilines.
Особенности мониторов.
digiterms:lcd_monitor предоставляет экран в 6 строк по 12 символов. Вывод скроллируется. То есть, можно видеть несколько последовательных выводов, в пределах собственного буфера вывода экрана.
digilines:lcd работает в режиме перезаписи - последний вывод и есть всё содержание экрана. Есть дополнительное свойство - при наведении на экран содержание последнего вывода отображается как статус объекта.
Привязка нескольких мониторов на один канал digiline дублирует информацию. Это может быть полезно для разнесения мониторов в удобные для наблюдения места или для использования двух разных типов мониторов.
Код, с примерами обработки. В данном случае
- порт А пустой,
- порт C подключён к
mesecons_lamp:lamp_off, - к какому-то порту, B или D, подключён датчик мезеконс-сигнала, например,
mesecons_button:button_off, - и к оставшемуся порту подключён тач-скрин с идентификатором ts1 и дисплей с идентификатором d1.
-- do return end -- выключатель, на всякий случай
-- функции приведения к тексту
---- состояния порта
local function iostr(pin)
return (pin and "1" or "0");
end
---- таблицы
local function tblstr(tbl)
tmp="";
if type(tbl) ~= "table" then
tmp= "="..type(tbl).."=";
else
for key, val in pairs(tbl) do
tmp=tmp.."("..key.."|"..type(val)..")";
end
end
return tmp;
end
-- внутренние функции
function loginit()
-- ! настраиваемые индикаторы дисплеев и тачскрина
mem.logscr="d1";
mem.logpan="ts1";
-- !
mem.log={};
mem.logmax=21;
mem.logcur=1;
mem.logfrs=1;
mem.logcmd={command="addlabel",X=1.1,Y=0.1,label="log"};
tscc={command="clear"};
tscl={command="addbutton",X=0.1,Y=0.1,W=1,H=1,name="blog",label="log"}
tscx={command="addbutton_exit",X=0.1,Y=1.1,W=1,H=1,name="bexit",label="X"}
mem.logset={tscc, tscl, tscx, mem.logcmd};
logmkl(); -- refresh mem.logcmd.label
digiline_send (mem.logscr, "\n\n\n\n\n\n"); -- clear lcd
digiline_send (mem.logpan, mem.logset); -- set touch screen
end
function log (txt)
digiline_send (mem.logscr, txt);
mem.log[mem.logcur]=txt;
mem.logcur=mem.logcur+1;
if mem.logcur >mem.logmax then
mem.logcur=1;
end
if (mem.logcur-mem.logfrs)<=0 then
mem.logfrs=mem.logfrs+1;
if mem.logfrs >mem.logmax then
mem.logfrs=1;
end
end
end
function relog ()
logmkl();
digiline_send(mem.logpan, mem.logset);
end
function logmkl()
ttmp=mem.log[mem.logfrs];
if (mem.logcur-mem.logfrs)==-1 then
ptmp=mem.logfrs;
for i=1,mem.logmax-2,1 do
ptmp=ptmp+1;
if ptmp >mem.logmax then ptmp=1 end
ttmp=ttmp.."\n"..mem.log[ptmp];
end
elseif (mem.logcur-mem.logfrs)>0 then
for i=mem.logfrs+1,mem.logcur-1,1 do
ttmp=ttmp.."\n"..mem.log[i];
end
end
mem.logcmd.label=ttmp;
end
-- ! пример собственный кнопок на тачскрине
tscA={command="addbutton",X=0.1,Y=3.1,W=1,H=1,name="but_a",label="A"}
tscB={command="addbutton",X=0.1,Y=4.1,W=1,H=1,name="but_b",label="B"}
-- !
-- ! собственные функции, примеры
function fA ()
log("fA: in");
port.c=true;
log("fA: out");
end
function fB ()
log("fB: in");
port={a=false;c=false};
log("fB: out");
end
-- !
function fmain ()
loginit();
log("main"); -- test log system
-- ! добавление собственных кнопок
mem.logset[#mem.logset+1]=tscA;
mem.logset[#mem.logset+1]=tscB;
-- !
-- ! Место для собственного кода основной программы
-- !
relog();
end
-- Обработчик прерываний
function fintr ()
log("intr");
-- ! Место для кода обработки прерываний
-- !
relog();
end
-- Обработчик диджилайн-событий
function fdigi ()
log(":dl:"..event.channel..":msg:"..tblstr(event.msg));
-- ******** logger *******
if (event.channel == mem.logpan) then
log(":dl-ts-clicker:"..event.msg.clicker);
if (event.msg.blog) then
relog();
elseif (event.msg.quit) then
relog();
-- ! пример обработки собственных кнопок
elseif (event.msg.but_a) then
log(":dl: button A pressed");
fA();
elseif (event.msg.but_b) then
log(":dl: button B pressed");
fB();
-- !
else
log(":dl: other log panel event")
relog();
end
-- ******** end logger *******
-- ! примеры обработки других диджилайн-событий
-- elseif (event.channel == "b1") then
--
-- elseif (event.channel == rtc1) then
--
-- elseif (event.channel == "io1") then
-- !
else
log("!oth digi:"..event.channel)
end
--digiline_send(mem.logpan, mem.logset);
relog();
end
-- ******** monitor *******
if (event.type == "program") then fmain()
elseif (event.type == "interrupt") then fintr()
elseif (event.type == "digiline") then fdigi()
elseif (event.type == "on") then
-- обработка мезеконс-события ON log(":on:a"..iostr(pin.a)..":b"..iostr(pin.b)..":c"..iostr(pin.c)..":d"..iostr(pin.d));
port.c=true;
relog();
elseif (event.type == "off") then
-- обработка мезеконс-события OFF log(":off:a"..iostr(pin.a)..":b"..iostr(pin.b)..":c"..iostr(pin.c)..":d"..iostr(pin.d))
relog();
else
-- и если будут реализование ещё какие-то события..
log("!oth event="..event.type);
relog();
end





