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

fasadik

Пользователи
  • Публикации

    9
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные пользователем fasadik


  1.  

     

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

     

    Постараюсь. 


  2. Подмена 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-код, где-то раз в пол секунды.

     

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

×
×
  • Создать...