Перейти к содержимому


Фотография

Подмена computer.pullSignal или методика построения резидентных программ в OpenOS

OC pullSignal TSR

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 29

#1 Оффлайн   swg2you

swg2you
  • Пользователи
  • Сообщений: 268
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

              

Отправлено 21 Июнь 2015 - 15:39

Подмена computer.pullSignal или методика построения резидентных программ в OpenOS
Допустим, захотелось нам иметь резидентную программу, которая будет работать на фоне OpenOS и, периодически, или по какому либо событию, что-то полезное делать.
 
Воспользуемся нашим маленьким bibi, а в качестве boot.lua напишем такой код:
local cl=component.list
local gp=component.proxy(cl("gpu")())

--сохраняем исходные функции из _G.computer, для внутреннего пользования
local cp={} for k,v in pairs(computer) do cp[k]=v end

--подменяем функцию computer.pullSignal
computer.pullSignal = function (...)
  local e={cp.pullSignal(...)}
 --для примера, по тильде (~) будем ребутать компьютер
  if e[1]=='key_down' and e[4]==41 then cp.shutdown(true) end
  --а по lAlt будем выводить список компонентов используя определенную в OpenOS функцию print и сохраненную cl
  if e[1]=='key_down' and e[4]==56 then
    for k,v in cl() do print(k,v) end
  end
  --OpenOS периодически сама дергает эвенты (чтобы курсор мигал и прочее) подробнее смотрите в lib/event.lua
  --поэтому мы можем выводить свои часики, куда-ж без них то ) и прочие полезности, например инфу о памяти
  local s=tostring(math.floor(cp.freeMemory()/1024))..'/'..tostring(cp.totalMemory()/1024)..' kb free '..os.date('!%R')
  local w,h = gp.maxResolution()
  gp.set(w-#s+1,1,s)
  --в конце мы должны вернуть событие ничего не подозревающей OpenOS
  return table.unpack(e)
end

--функцию мы подменили, теперь загружаем, компилируем и выполняем init.lua
local fs=component.proxy(computer.getBootAddress())
local h=fs.open('init.lua')
local s,r='',''
while r do
  r=fs.read(h,math.huge)
  s=s..(r or "")
end
fs.close(h)
load(s)()
Запускаем компьютер, bibi пискнув и подождав секундочку, выполняет наш boot.lua, который хитро подменив pullSignal выполнит init.lua и после загрузки OpenOS в углу экрана радостно затикают часики.

h_1434887575_1643213_5ca46d9108.png

Теперь мы можем нажать lAlt и лицезреть список компонентов, или нажать тильду, и компьютер перезапустится.
--==--
Конечно, вы можете сказать, что вывод списка компонентов портит экран, что перед выводом хорошо бы сохранять состояние экрана каким-нибудь gpu.get, вывод делать в свой интерфейс, а после, восстанавливать экран. И часики у меня никудышние. При скролле вниз (например в редакторе edit.lua) скроллируются вместе с текстом, вместо того, чтобы оставаться там где им положено. Но моя задача, показать метод на простейших примерах, а не переопределяя gpu строить интерфейсы.
 
На основе этого метода можно построить API для TSR программ, а комбинируя его с перехватом component.proxy, component.invoke и последующей подменой gpu на виртуальный терминал, и вовсе, написать свою операционную систему. Для которой, кстати говоря, было бы неплохо уметь запускать OpenOS в окошке, но самое главное, в изолированной среде, чтобы труд программистов писавших ПО под OpenOS не пропадал зря.
 
Я бы даже сказал, что изоляция OpenOS, на данном этапе, более важная задача, чем построение интерфейсов. Поэтому мы попробуем разобрать эту проблему в следующей статье.
 
Посмотрим что выйдет.
--==--
Небольшое дополнение:
Если вам не охота играть с bibi, но нужно запустить резидентную программу прямо из-под OpenOS, то это сделать еще проще.
local component = require("component")
local cp = require("computer")
local gpu = component.gpu
local pullSignal = cp.pullSignal

cp.pullSignal = function (...)
  local e={pullSignal(...)}
  if e[1]=='key_down' and e[4]==41 then cp.shutdown(true) end
  if e[1]=='key_down' and e[4]==56 then for k,v in component.list() do print(k,v) end end
  local s=' '..math.floor(cp.freeMemory()/1024)..'/'..(cp.totalMemory()/1024)..' kb free  '..os.date('!%R')
  local w,h = gpu.maxResolution() gpu.set(w-#s+1,1,s)  
  return table.unpack(e)
end
Сохраняем этот код в файл, допустим tsr.lua и запускаем его под OpenOS
Программа выполнится, завершится, а резидентный участок останется в памяти.
--==--
Если выбросить все что относится к демонстрации работы, у нас останется маленькая обертка
local cp = require("computer")
local pullSignal = cp.pullSignal
cp.pullSignal = function (...)
  local e={pullSignal(...)}

  --код TSR программы

  return table.unpack(e)
end
Заключив в которую код своей TSR программы мы получим резидента, который будет выполнять TSR-код, где-то раз в пол секунды.

Сообщение отредактировал swg2you: 21 Июнь 2015 - 23:15


#2 Оффлайн   Doob

Doob
  • Пользователи
  • Сообщений: 814
  • Уровень сигнала: 17,03%
  • В игре: 146 час. 10 мин.

Награды

                                   

Отправлено 21 Июнь 2015 - 15:47

Это круто! Я все никак не мог сообразить, как такое провернуть, спасибо, чувак!



#3 Оффлайн   swg2you

swg2you
  • Автор темы
  • Пользователи
  • Сообщений: 268
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

              

Отправлено 21 Июнь 2015 - 17:08

Это круто! Я все никак не мог сообразить, как такое провернуть, спасибо, чувак!

Пожалуйста, чувак )
 
upd:
перенес дополнение в первый пост

Сообщение отредактировал swg2you: 21 Июнь 2015 - 23:16


#4 Оффлайн   Krutoy

Krutoy
  • Гуру
  • Сообщений: 499
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

              

Отправлено 21 Июнь 2015 - 18:47

Неплохо, но похоже, я догадываюсь к чему это всё идет. Еще немного и swg2you напишет свою ось. Ось для Биосов.

А что, слабо написать ось на 4к памяти?



#5 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 213
  • Уровень сигнала: 13,71%
  • В игре: 117 час. 41 мин.
  • ГородЛуна

Награды

                       

Отправлено 21 Июнь 2015 - 19:54

Неплохо, но похоже, я догадываюсь к чему это всё идет. Еще немного и swg2you напишет свою ось. Ось для Биосов.
А что, слабо написать ось на 4к памяти?

Все идёт к тому что я собираюсь открыть проект MNL (MNL's Not Linux), копию ядра линукс, только под Lua Opencomputers и со своим преферансом и мормуазелями.

И писать на биосе по мне --- тупиковая ветвь развития. Все упрется в то, что ты достигнет лимита.

#6 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 015
  • Уровень сигнала: 149,05%
  • В игре: 1279 час. 35 мин.

Награды

                                               

Отправлено 21 Июнь 2015 - 20:06

Все идёт к тому что я собираюсь открыть проект MNL (MNL's Not Linux), копию ядра линукс, только под Lua Opencomputers и со своим преферансом и мормуазелями.

И писать на биосе по мне --- тупиковая ветвь развития. Все упрется в то, что ты достигнет лимита.

Открыть и забыть. Интересное решение.

 

 

Неплохо, но похоже, я догадываюсь к чему это всё идет. Еще немного и swg2you напишет свою ось. Ось для Биосов.

А что, слабо написать ось на 4к памяти?

ОСь загруженная в темпе из инета (и/или по ОпенНет) и запускаемая из-под биоса... Интересно)



#7 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 213
  • Уровень сигнала: 13,71%
  • В игре: 117 час. 41 мин.
  • ГородЛуна

Награды

                       

Отправлено 21 Июнь 2015 - 22:27

ОСь загруженная в темпе из инета (и/или по ОпенНет) и запускаемая из-под биоса... Интересно)


Вот и Сони так думают. Вон уже консоли в сервера несут, будет так: проплатил - играешь, не проплатил - не играешь.

#8 Оффлайн   Zer0Galaxy

Zer0Galaxy
  • Гуру
  • Сообщений: 1 230
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

   5                              

Отправлено 22 Июнь 2015 - 12:37

swg2you, я смотрю, ты как и некоторые здесь, любитель переопределять системные функции. Предлагаю тебе и другим желающим реализовать совместно проект FTP. Для доступа к дисковому пространству удаленного компьютера по вайфаю или ОпенНет.

Это должна быть резидентная программа, которая подменяет функции библиотеки filesystem таким образом, что обращение к папке, расположенной на другом компьютере, выглядит как работа с локальным диском.



#9 Онлайн   NEO

NEO
  • Пользователи
  • Сообщений: 1 780
  • Уровень сигнала: 4,24%
  • В игре: 36 час. 25 мин.
  • ГородСолнце

Награды

   3                        

Отправлено 22 Июнь 2015 - 12:52

swg2you, я смотрю, ты как и некоторые здесь, любитель переопределять системные функции. Предлагаю тебе и другим желающим реализовать совместно проект FTP. Для доступа к дисковому пространству удаленного компьютера по вайфаю или ОпенНет.

Это должна быть резидентная программа, которая подменяет функции библиотеки filesystem таким образом, что обращение к папке, расположенной на другом компьютере, выглядит как работа с локальным диском.

Я когда-то под CC такое делал.



#10 Оффлайн   Zer0Galaxy

Zer0Galaxy
  • Гуру
  • Сообщений: 1 230
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

   5                              

Отправлено 22 Июнь 2015 - 13:03

Я тоже делал. А вот на ОС решил и чую, зарываюсь. Намного сложнее тут ось построена.



#11 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 213
  • Уровень сигнала: 13,71%
  • В игре: 117 час. 41 мин.
  • ГородЛуна

Награды

                       

Отправлено 22 Июнь 2015 - 13:21

Разве OpenCloud не заменит функции ftp?

#12 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 015
  • Уровень сигнала: 149,05%
  • В игре: 1279 час. 35 мин.

Награды

                                               

Отправлено 22 Июнь 2015 - 20:21

Разве OpenCloud не заменит функции ftp?

Какой OpenCloud?? Во-первых, вы его никогда, похоже, не допишете.

Во-вторых, не путай FTP с облаком. Это две разные вещи!

В первом случае — это резидентная программа, а во втором — интерфес мост — сервер.



#13 Онлайн   NEO

NEO
  • Пользователи
  • Сообщений: 1 780
  • Уровень сигнала: 4,24%
  • В игре: 36 час. 25 мин.
  • ГородСолнце

Награды

   3                        

Отправлено 22 Июнь 2015 - 20:28

Какой OpenCloud?? Во-первых, вы его никогда, похоже, не допишете.

Во-вторых, не путай FTP с облаком. Это две разные вещи!

В первом случае — это резидентная программа, а во втором — интерфес мост — сервер.

:giggle:  :smile148:  Ага не допишем. :smile3:



#14 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 213
  • Уровень сигнала: 13,71%
  • В игре: 117 час. 41 мин.
  • ГородЛуна

Награды

                       

Отправлено 22 Июнь 2015 - 20:32

:smile3:  :smile3:  :smile3:  :smile3:  :smile3:



#15 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 015
  • Уровень сигнала: 149,05%
  • В игре: 1279 час. 35 мин.

Награды

                                               

Отправлено 22 Июнь 2015 - 21:08

:giggle:  :smile148:  Ага не допишем. :smile3:

Тогда полный вперёд. А то прогресс стоит, ничего не делается.

Кстати, посмотрите на тему. Потом на сообщение своё. Потом снова на тему. Потом на Правила.



#16 Оффлайн   swg2you

swg2you
  • Автор темы
  • Пользователи
  • Сообщений: 268
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

              

Отправлено 22 Июнь 2015 - 22:36

2Krutoy
>...А что, слабо написать ось на 4к памяти?
34816 бит, без учета "имени", это довольно много.
 
2LeshaInc
>...И писать на биосе по мне --- тупиковая ветвь развития...
тупиковая - не писать.
 
2Fingercomp
>...ОСь загруженная в темпе из инета (и/или по ОпенНет) и запускаемая из-под биоса... Интересно)
Биос такой, - Сосед, а сосед, ты один пинганулся на этом порту, а дай мне код операционки, чтоб я в инет сам не лез!
- Ты офигел? я вообще-то дрон и у меня ос, из других модулей состоит. Хочешь дроном стать?
- Дроном мне не судьба. Максимум - роботом, - Рожденный ползать... - как там говорится.
- Летать не может, - там говорится.
- Ну слетай к кому нибудь, принеси, а?
- Ага, щас. С инета тяни. Или жди пока еще кто из твоей породы проснется и потянет.
- Так хозяин инет-карту куда й то запропастил. Вчерась еще была, а сегодня - тык, - нету!


2Zer0Galaxy
>...Это должна быть резидентная программа,...
как минимум две.

#17 Оффлайн   davial

davial
  • Пользователи
  • Сообщений: 454
  • Уровень сигнала: 14,24%
  • В игре: 122 час. 17 мин.
  • ГородТроон в системе Канопуса.

Награды

                       

Отправлено 25 Июнь 2015 - 18:17

У одного меня родилась ассоциация : " Резидентная программа --> Вирус " ?



#18 Оффлайн   swg2you

swg2you
  • Автор темы
  • Пользователи
  • Сообщений: 268
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

              

Отправлено 25 Июнь 2015 - 21:12

У одного меня родилась ассоциация : " Резидентная программа --> Вирус " ?

Это один из вариантов использования резидентных программ



#19 Оффлайн   davial

davial
  • Пользователи
  • Сообщений: 454
  • Уровень сигнала: 14,24%
  • В игре: 122 час. 17 мин.
  • ГородТроон в системе Канопуса.

Награды

                       

Отправлено 25 Июнь 2015 - 21:25

Это один из вариантов использования резидентных программ

Мне больше это нравится :)


Сообщение отредактировал davial: 25 Июнь 2015 - 21:26


#20 Оффлайн   Asummonster

Asummonster
  • Пользователи
  • Сообщений: 570
  • Уровень сигнала: 42,92%
  • В игре: 368 час. 28 мин.
  • ГородКиев

Награды

                    

Отправлено 25 Июнь 2015 - 21:36

Мне больше это нравится :)

Из того,что я прочитал - такой демон может отвечать,к примеру,на автоматическое монтирование дисков(ивент peripheralAdded, на сколько я помню), автоматически прогружать в глобал АПИ компонентов(что бы каждый раз не писать modem=component.modem), работать корзиной и т.п. Вобщем - может быть не только вирусом. Часики swg тоже демон,в винде его бы назвали "служба гаджета часов"



#21 Оффлайн   swg2you

swg2you
  • Автор темы
  • Пользователи
  • Сообщений: 268
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

              

Отправлено 26 Июнь 2015 - 07:04

Из того,что я прочитал - такой демон может отвечать,к примеру,на автоматическое монтирование дисков(ивент peripheralAdded, на сколько я помню), автоматически прогружать в глобал АПИ компонентов(что бы каждый раз не писать modem=component.modem), работать корзиной и т.п. Вобщем - может быть не только вирусом. Часики swg тоже демон,в винде его бы назвали "служба гаджета часов"

Службы, демоны, резиденты - каких только имен не наплодили для фоновых задач )


  • Totoro, Asummonster и Kartze это нравится

#22 Оффлайн   HeroBrine1st

HeroBrine1st
  • Пользователи
  • Сообщений: 80
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

           

Отправлено 14 Март 2017 - 20:11

swg2you, я смотрю, ты как и некоторые здесь, любитель переопределять системные функции. Предлагаю тебе и другим желающим реализовать совместно проект FTP. Для доступа к дисковому пространству удаленного компьютера по вайфаю или ОпенНет.

Это должна быть резидентная программа, которая подменяет функции библиотеки filesystem таким образом, что обращение к папке, расположенной на другом компьютере, выглядит как работа с локальным диском.

легче создать proxy диска компьютера, который сам будет обращаться к другому компу и получать с него данные, а потом возвращать. потом через fs.mount смонтировать, или работать напрямую через прокси



#23 Оффлайн   Zer0Galaxy

Zer0Galaxy
  • Гуру
  • Сообщений: 1 230
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Награды

   5                              

Отправлено 15 Март 2017 - 00:12

легче создать proxy диска компьютера, который сам будет обращаться к другому компу и получать с него данные, а потом возвращать. потом через fs.mount смонтировать, или работать напрямую через прокси

Да я уж давно сделал и забыл про это.

#24 Оффлайн   TC1061

TC1061
  • Пользователи
  • Сообщений: 39
  • Уровень сигнала: 6,93%
  • В игре: 59 час. 28 мин.

Отправлено 17 Апрель 2017 - 19:52

легче создать proxy диска компьютера, который сам будет обращаться к другому компу и получать с него данные, а потом возвращать. потом через fs.mount смонтировать, или работать напрямую через прокси

дадададададдадададада классная идея это надо будет изменить component.proxy к примеру чтобы если она получила "network" то тогда возвратила прокси сети компов с этой же прогой. Но это не все - ведь если резидентная программа будет только требовать файлы из сети - кто ей даст? Никто. Поэтому нужно сделать функцию распространения файликов к примеру через копирование файлов в папку "network/mf" ("network" - туда мы смонтируем сетевую FS) и выбрав загрузочную ФС для хранения сетевых файлов (т. е. в папке etc создать mf которая будет отображаться также и в прокси сетевой FS). Это будет шикарно если сделать. Суперская ФТП получится



#25 Оффлайн   fasadik

fasadik
  • Пользователи
  • Сообщений: 11
  • Уровень сигнала: 2,67%
  • В игре: 22 час. 53 мин.

Отправлено 20 Июнь 2017 - 21:56

Подмена computer.pullSignal или методика построения резидентных программ в OpenOS
Допустим, захотелось нам иметь резидентную программу, которая будет работать на фоне OpenOS и, периодически, или по какому либо событию, что-то полезное делать.
 
Воспользуемся нашим маленьким bibi, а в качестве boot.lua напишем такой код:

local cl=component.list
local gp=component.proxy(cl("gpu")())

--сохраняем исходные функции из _G.computer, для внутреннего пользования
local cp={} for k,v in pairs(computer) do cp[k]=v end

--подменяем функцию computer.pullSignal
computer.pullSignal = function (...)
  local e={cp.pullSignal(...)}
 --для примера, по тильде (~) будем ребутать компьютер
  if e[1]=='key_down' and e[4]==41 then cp.shutdown(true) end
  --а по lAlt будем выводить список компонентов используя определенную в OpenOS функцию print и сохраненную cl
  if e[1]=='key_down' and e[4]==56 then
    for k,v in cl() do print(k,v) end
  end
  --OpenOS периодически сама дергает эвенты (чтобы курсор мигал и прочее) подробнее смотрите в lib/event.lua
  --поэтому мы можем выводить свои часики, куда-ж без них то ) и прочие полезности, например инфу о памяти
  local s=tostring(math.floor(cp.freeMemory()/1024))..'/'..tostring(cp.totalMemory()/1024)..' kb free '..os.date('!%R')
  local w,h = gp.maxResolution()
  gp.set(w-#s+1,1,s)
  --в конце мы должны вернуть событие ничего не подозревающей OpenOS
  return table.unpack(e)
end

--функцию мы подменили, теперь загружаем, компилируем и выполняем init.lua
local fs=component.proxy(computer.getBootAddress())
local h=fs.open('init.lua')
local s,r='',''
while r do
  r=fs.read(h,math.huge)
  s=s..(r or "")
end
fs.close(h)
load(s)()
Запускаем компьютер, bibi пискнув и подождав секундочку, выполняет наш boot.lua, который хитро подменив pullSignal выполнит init.lua и после загрузки OpenOS в углу экрана радостно затикают часики.

h_1434887575_1643213_5ca46d9108.png

Теперь мы можем нажать lAlt и лицезреть список компонентов, или нажать тильду, и компьютер перезапустится.
--==--
Конечно, вы можете сказать, что вывод списка компонентов портит экран, что перед выводом хорошо бы сохранять состояние экрана каким-нибудь gpu.get, вывод делать в свой интерфейс, а после, восстанавливать экран. И часики у меня никудышние. При скролле вниз (например в редакторе edit.lua) скроллируются вместе с текстом, вместо того, чтобы оставаться там где им положено. Но моя задача, показать метод на простейших примерах, а не переопределяя gpu строить интерфейсы.
 
На основе этого метода можно построить API для TSR программ, а комбинируя его с перехватом component.proxy, component.invoke и последующей подменой gpu на виртуальный терминал, и вовсе, написать свою операционную систему. Для которой, кстати говоря, было бы неплохо уметь запускать OpenOS в окошке, но самое главное, в изолированной среде, чтобы труд программистов писавших ПО под OpenOS не пропадал зря.
 
Я бы даже сказал, что изоляция OpenOS, на данном этапе, более важная задача, чем построение интерфейсов. Поэтому мы попробуем разобрать эту проблему в следующей статье.
 
Посмотрим что выйдет.
--==--
Небольшое дополнение:
Если вам не охота играть с bibi, но нужно запустить резидентную программу прямо из-под OpenOS, то это сделать еще проще.
local component = require("component")
local cp = require("computer")
local gpu = component.gpu
local pullSignal = cp.pullSignal

cp.pullSignal = function (...)
  local e={pullSignal(...)}
  if e[1]=='key_down' and e[4]==41 then cp.shutdown(true) end
  if e[1]=='key_down' and e[4]==56 then for k,v in component.list() do print(k,v) end end
  local s=' '..math.floor(cp.freeMemory()/1024)..'/'..(cp.totalMemory()/1024)..' kb free  '..os.date('!%R')
  local w,h = gpu.maxResolution() gpu.set(w-#s+1,1,s)  
  return table.unpack(e)
end
Сохраняем этот код в файл, допустим tsr.lua и запускаем его под OpenOS
Программа выполнится, завершится, а резидентный участок останется в памяти.
--==--
Если выбросить все что относится к демонстрации работы, у нас останется маленькая обертка
local cp = require("computer")
local pullSignal = cp.pullSignal
cp.pullSignal = function (...)
  local e={pullSignal(...)}

  --код TSR программы

  return table.unpack(e)
end
Заключив в которую код своей TSR программы мы получим резидента, который будет выполнять TSR-код, где-то раз в пол секунды.

 

А как убрать это из памяти?



#26 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 015
  • Уровень сигнала: 149,05%
  • В игре: 1279 час. 35 мин.

Награды

                                               

Отправлено 20 Июнь 2017 - 22:08

А как убрать это из памяти?

Гм, может, "Войну и мир" в цитату ещё запихнуть, чтобы потом написать " :smile9: "? Отрезайте ту часть цитаты, на которую отвечаете (а тут цитировать вообще не нужно было).

 

По поводу вопроса самого. Прежнее значение computer.pullSignal должно быть сохранено в другую переменную. Заменой переопределённой функции на изначальную можно остановить выполнение программы.

Из памяти затем программа будет потёрта при следующей сборке мусора, если на неё не осталось ссылок.


Сообщение отредактировал Fingercomp: 20 Июнь 2017 - 22:09


#27 Оффлайн   fasadik

fasadik
  • Пользователи
  • Сообщений: 11
  • Уровень сигнала: 2,67%
  • В игре: 22 час. 53 мин.

Отправлено 20 Июнь 2017 - 22:14

Гм, может, "Войну и мир" в цитату ещё запихнуть, чтобы потом написать " "? Отрезайте ту часть цитаты, на которую отвечаете (а тут цитировать вообще не нужно было).

 

Постараюсь. 



#28 Оффлайн   fasadik

fasadik
  • Пользователи
  • Сообщений: 11
  • Уровень сигнала: 2,67%
  • В игре: 22 час. 53 мин.

Отправлено 20 Июнь 2017 - 22:18

должно быть сохранено в другую переменную. Заменой переопределённой функции на изначальную
 

То есть? Можешь как для дебила объяснить,а то я не умней этого статуса :\ 



#29 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 015
  • Уровень сигнала: 149,05%
  • В игре: 1279 час. 35 мин.

Награды

                                               

Отправлено 21 Июнь 2017 - 07:58

То есть? Можешь как для дебила объяснить,а то я не умней этого статуса :\ 

Да без проблем, я тут для этого и сижу.

 

computer.pullSignal — это low-level функция, то есть в обычных программах её напрямую нечасто используют (редко когда действительно необходимо). Всё, что она делает — получает события из некоторой копилки событий. Например, 100 раз тыкнул на клавишу — в копилке появилось 100 событий, и этой функцией они могут быть получены в коде.

Но пока напрямую используют немногие, косвенно — вызовом os.sleep и event.pull — почти во всех.

 

И появляется интересная мысль. Что если заменить функцию computer.pullSignal на свою? Она всё ещё будет делать изначальную работу, но при каждом запросе ивента заодно выполнит какой-то дополнительный код, как, например, отрисовку часиков, как в оригинальном посте.
 

Первое, что приходит на ум:

function computer.pullSignal(...)
  print("Hello, world!")
  return computer.pullSignal(...)
end

Переопределённая функция наша тогда возьмёт все переданные ей аргументы и скормит их изначальной, попутно написав "Hello, world!" В теории.

На практике получается так, что мы переопределили computer.pullSignal и для самой себя, поэтому потонем в бесконечной рекурсии. Прикольно, но вряд ли нам это нужно. Наверное.

 

Чтобы такого не было, надо сохранить прежнее значение computer.pullSignal в отдельную переменную и использовать уже её.

-- сохранились
local pullSignal = computer.pullSignal

function computer.pullSignal(...)
  print("Hello, world!")
  return pullSignal(...)
end

Та-дам: всё работает.

 

Теперь попробуем отключить переопределённую функцию. Тут всё очень просто. Например, вот как можно сделать так, чтобы отключаться при нажатии "Enter":

local kbd = require("keyboard")

local pullSignal = computer.pullSignal

function computer.pullSignal(...)
  local e = table.pack(pullSignal(...))
  if e[1] == "key_down" and e[4] == kbd.keys.enter then
    computer.pullSignal = pullSignal
  end
  return table.unpack(e)
end

По сравнению с предыдущим сниппетом кода, поменялось вот что:

  1. Мы получаем событие до выполнения своего кода и сохраняем в таблицу e.
  2. Выполняем свой код (при нажатии Enter снова подменяем computer.pullSignal, но на этот раз на стандартное значение).
  3. Возвращаем ивент.

 

У такого метода использования есть недостатки. Если два скрипта подменят одну и ту же функцию, проблематично будет отключить программы. Ещё функция запускается только при вызове computer.pullSignal, а не с каким-то интервалом. Система будет тормозить, если эту функцию заменить на какую-то, которая будет небыстро работать. И так далее.

 

Поэтому лучше для обработки ивентов использовать event.listen, для вызова функции по интервалу — event.listen, а для поочерёдной работы нескольких потов — стандартную в грядущей OpenOS 1.6.4 и выше библиотеку "thread" — или, пока OC не обновился, либу от Zer0Galaxy.


  • eu_tomat и fasadik это нравится

#30 Оффлайн   fasadik

fasadik
  • Пользователи
  • Сообщений: 11
  • Уровень сигнала: 2,67%
  • В игре: 22 час. 53 мин.

Отправлено 21 Июнь 2017 - 10:45

либу от Zer0Galaxy.
 

Я пытался но не работает файлы не выполняються.







Темы с аналогичным тегами OC, pullSignal, TSR

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных