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

swg2you

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

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

  • Посещение

  • Победитель дней

    20

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


  1. ro = {a=1, b=2}
    obj = {b=3, c=4}
    setmetatable(obj,{__index=ro,__newindex=function(_,_,_)end})
    
    prn(obj.a, obj.b, obj.c) -->1 3 4 (значение obj.b=3 установленное до объявления метаметодов перекрывает ro.b=2, и __index=ro не вызывается.
    obj.a=5
    obj.b=6
    obj.c=7
    prn(obj.a, obj.b, obj.c) -->1 6 7 (obj.a=5 выполнил function(_,_,_)end ничего не сделав)
    
     

    Эта строка setmetatable(obj, {__index=ro, __newindex=function(_,_,_)end}) говорит следующее:

    Для несуществующих индексов таблицы obj, читать значения из ro, а при попытке записи выполнять ничего function(_,_,_)end

     

    Или так: setmetatable(obj,{__index=ro,__newindex=function(t,k,v) print('Иди в пень! '..k..' ' - ридонли!')  end})

     

    --===--

     

    При попытке добавления нового значения (например obj.d=8) выполнится ничего и значение добавлено не будет.

    Чтобы мы могли добавлять новые индексы в obj нужно в нашем ничего проверять, есть ли добавляемый индекс в ro, и если такого индекса нет, то добавлять его в obj.

     

    Это можно сделать так: setmetatable(obj, {__index=ro,__newindex=function(t,k,v) local _=rawget(ro,k) or rawset(t,k,v) end})

    При попытке записи obj.d=8, наше ничего, сделает: если не ro.k то rawset(t,k,v) наплевав на всякие там метаметамета.

     

    Теперь мы можем:

    ro = {a=1, b=2}
    obj = {b=3, c=4}
    setmetatable(obj,{__index=ro,__newindex=function(t,k,v) local _=rawget(ro,k) or rawset(t,k,v) end})
    
    prn(obj.a, obj.b, obj.c, obj.d)
    obj.a=5
    obj.b=6
    obj.c=7
    obj.d=8
    prn(obj.a, obj.b, obj.c, obj.d)
    
    upd:

    Прочел следующие посты и понял, как я далек от объектно-ориентированного програмирования )


  2. Ok, в кабинки заходят игроки, кликают по мониторам - поршни запирают вход.

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

    Выход/вылет/warp - одним/обеими игроками - как обрабатывать?

  3. 2@Krutoy

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

    34816 бит, без учета "имени", это довольно много.

     

    2@LeshaInc

    >...И писать на биосе по мне --- тупиковая ветвь развития...

    тупиковая - не писать.

     

    2@Fingercomp

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

    Биос такой, - Сосед, а сосед, ты один пинганулся на этом порту, а дай мне код операционки, чтоб я в инет сам не лез!

    - Ты офигел? я вообще-то дрон и у меня ос, из других модулей состоит. Хочешь дроном стать?

    - Дроном мне не судьба. Максимум - роботом, - Рожденный ползать... - как там говорится.

    - Летать не может, - там говорится.

    - Ну слетай к кому нибудь, принеси, а?

    - Ага, щас. С инета тяни. Или жди пока еще кто из твоей породы проснется и потянет.

    - Так хозяин инет-карту куда й то запропастил. Вчерась еще была, а сегодня - тык, - нету!

     

     

    2@Zer0Galaxy

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

    как минимум две.


  4. Я не приставучий, я не люблю когда не правильно пишут термины.

    Ты не понял термина, ну бывает.

    Отвечать тебе больше не буду так как знаю что такой спор будет долго длиться, да и всё равно в конце концов ты поймёшь термин интерпретация, и компиляция, и в чём их разница.

    Ок, ок. Прости за грубость. Спор действительно на пустом месте.

    Пойду я, а то у меня еще мой коблоужас на сервере не достроен.

    Еще рас прошу извинить и, надеюсь, мир?


  5. Интересное применение рекурсии.
     
    Написание своей функции сортировки полезно, как минимум, для изучения применения рекурсии в алгоритмах сортировки. Но на практике, я предпочитаю встроенную table.sort

    local arr={1,3,6,2,7,4,8,9,5}
    print(table.unpack(arr))
    
    --по возрастанию
    table.sort(arr) 
    print(table.unpack(arr))
    
    --по убыванию, или по своему признаку
    table.sort(arr,function(a,b) return a>b end)
    print(table.unpack(arr))
    

  6. Каждый компилятор после своей работы оставляет файл с машинным или байт кодом.

    А интерпретатор может упрощать конструкции что бы постоянно не анализировать.

    У тебя бомбит :smile3:  :smile3:  :smile3:  Есть специальный компилятор LuaJIT http://luajit.org, а в OC стоит просто Lua interpreter.

    Который интерпретирует.

    Ух приставучий. Иди учись. Не трать моё время!


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

    Пожалуйста, чувак )

     

    upd:

    перенес дополнение в первый пост


  8. Велосипеды изобретаете. Все уже изобретено до нас. Какие коммивояжеры? Какие вычисления?

    Берем GPS API, берем Vector API, сканируем, перебором вычисляем рудные жилы (условие: несколько блоков ожидаемой плотности), заносим рудные жилы по-блочно в массив, в цикле трилатерируем ближайший нужный блок, едем в него, удаляем его из массива. И так далее, до каждого блока.

    Это "алгоритм ближайшего соседа" решающий "задачу коммивояжера" которая, в свою очередь, является частным случаем "задачи о кратчайшем пути". Так что насчет велосипедов - неясно )

     

    К слову, "алгоритм ближайшего соседа" простой, но очень неэффективный. "муравьями" решать эту задачу намного лучше.


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

  10. Писать программы для eeprom - то еще занятие. Попробуем облегчить этот процесс.

    • в \config\OpenComputers.cfg устанавливаем bufferChanges=false
    Это отключит буферизацию, и все изменения файлов в каталогах сохранения будут немедленно отображены внутри игры
    • Загружаем игру в сингл, строим себе базу, ставим там компьютер, и инсталлируем на него OpenOS.
    После этого, в каталоге \saves\%save_name%\opencomputers\ появится UID нашего виртуального "винчестера", со всем содержимым
    • Записываем туда файл bibi
    local gpu = component.proxy(component.list("gpu")())
    gpu.bind(component.list("screen")()) 
    
    local cy=1
    prn=function(...)
      local t={...}  
      for i=1,#t do t[i]=tostring(t[i]) end
      gpu.set(1,cy,table.concat(t, ' '))
      cy=cy+1
    end
    
    local readfile=function(f)
      for addr in component.list("filesystem") do
        local fs=component.proxy(addr)
        local h=fs.open(f)
        if h then
          --костыль для init.lua
          computer.getBootAddress=function() return addr end
          local s,r='',''
          while r do
            r=fs.read(h,math.huge)
            s=s..(r or "")
          end
          fs.close(h) 
          return s,f
        end
      end
    end
    
    prn('bibi: press a key to force init.lua') computer.beep(440)
    local s,f=readfile('boot.lua')
    if ({computer.pullSignal(1)})[1]=='key_down' or not s then 
      s,f=readfile('init.lua')
    end
    
    if s then
      local r,e=load(s,f)
      if r then r,e=pcall(r) end
      prn('bibi:', r, e)
    else
      prn('bibi: no file')
    end
    
    prn('bibi: press a key to reboot')
    repeat until ({computer.pullSignal()})[1]=='key_down'
    computer.shutdown(true) 
    • И файл boot.lua
    prn('Hello world', nil~=false)
    
    После чего в OpenOS делаем:
    • flash -q bibi bibi
    • reboot
    h_1434835970_5235428_e2d021c481.png

     

    Наблюдаем наш хелловорлд и убеждаемся, что nil и false - это две большие разницы:

     

    h_1434837050_8115362_ab38e16a39.png

     

    Теперь открываем наш boot.lua в блокноте или в чем вам удобно писать код, разминаем мозги и пальцы и погружаемся в процесс творчества.

    В одном окне блокнот с кодом, в другом - майнкрафт с нашим виртуальным компьютером. Написали-сохранили-проверили.

    ---

    Ошибки компиляции нашего кода будут выглядеть так:

    h_1434837050_7948091_48364a2896.png

     

    Ошибки выполнения так:

    h_1434837050_1573462_b1d2246271.png

    • А если нам захочется в OpenOS то мы нажмем секретную кнопку "а кей" когда наш bibi пискнет при старте.
    Также в OpenOS мы попадем если bibi не найдет файла boot.lua. А если и init.lua не найдет, то скажет "no file" и будет ждать когда мы исправим ситуацию

     

    ЗЫ

    Не злоупотребляйте prn(), она очень служебная и не умеет scroll, конечно scroll это всего лишь условие и две строки, но зачем?!

    Пишите свои prn-ы с преферансом и барышнями, предварительно поиграв ну хотя-бы с таким вот хелловорлдом:

     

    boot.lua для экспериментов:

    --биндим гпу со скрином
    local gpu = component.proxy(component.list("gpu")())
    gpu.bind(component.list("screen")())
    
    --стираем
    local sw, sh = gpu.maxResolution(); gpu.fill(1,1,sw,sh," ")
    
    --наши прн-ы с преферансом но без барышень
    function prnto(x,y,...)
      local t={...}
      for i=1,#t do t[i]=tostring(t[i]) end
      gpu.set(x,y,table.concat(t, ' '))
    end
    
    local cy=1
    function prn(...)
      prnto(1,cy,...)
      if cy==sh then
        gpu.copy(1,1,sw,sh,0,-1)
        gpu.fill(1,sh,sw,1," ")
      else
        cy=cy+1
      end
    end
    
    --хелловорлдим
    prn('Hello world', nil~=false)
    
    --глобалим
    for k,v in pairs(_G.component) do prn(k,v) end
    
    --компонентим
    for k,v in component.list() do prn(k,v) end
    
    --ииииииии
    while true do
      local e={computer.pullSignal(.833)}
      
      --часики-и-и
      local s=tostring(math.floor(computer.freeMemory()/1024))..'/'..tostring(computer.totalMemory()/1024)..' kb free '..os.date('!%R')
      prnto(sw-#s+1,1,s)
    
      --ну и прочие эвенты с юникодами
      if e[1] then 
        e[2]=tostring(e[2]):sub(1,3)..'~' -- обрезаем адрес компонента
        prn(table.unpack(e))
        if e[1]=='key_down' and e[3]~=0 then prn(unicode.char(e[3])) end
      end
    
      --а по тильде (~) все сначала
      if e[1]=='key_down' and e[4]==41 then computer.shutdown(true) end
    end
    

     

    • Нравится 5
    • Спасибо 1

  11. Вот-вот. В 100 раз снижены затраты энергии на ЧЛ, 0.01 скорость износа инструментов относительно игрока, апнут гео  -  копай, не хочу называется=)

    Если в 100 раз уменьшен износ инструмента, то получается что даже золотые кирки зачаровывать целесообразно?


  12. "Класть в робота образцы руд" что простите?! Может лучше образцы мусора тогда?

    Ну не знает еще человек, как апгрейды использовать. С апгрейдом "контроллер инвентаря" можно сразу выкидывать мусор по списку и не занимать слоты.

    Ребятки, критикуя не поняв сути вы выглядите глупо.

  13. И? Мне путь находить не требуется, задача состоит не в этом

    Разве?

     

    Строишь граф:

    Блоки руды = узлы

    Вес рёбер = количество энергии для перемещения робота в узел

     

    Алгоритм пробегает по этому графу и выдает "кратчайший" путь который и будет самой эффективной "жилой" с точки зрения затрат энергии.

     

    Если нужно минимизировать время - то в качестве веса рёбер бери время телодвижений робота.

    Если нужно минимизировать расстояние - то расстояние.

     

    Какой параметр выберешь в качестве веса ребра по тому параметру и будет проводиться оптимизация.


  14. по умолчанию режим HTML отключен,пока не переключишь принудительно..

    Эм. Мы недопоняли друг-друга, код который я привел скопирован из кода страницы а не из редактора. Редактор был в стандартном режиме, я отредактировал сообщение, оформив список багофич в виде маркированного списка, и после сохранения маркированный список разъехался. Редактор почему-то добавил к каждому элементу списка тег <br> 

    <li>- computer.shutdown(true) - не работает</li><br />

     

    А псевдо-html режим по первой кнопке - работает лучше чем wysiwyg.


  15. чем? 

    А хотя бы этим:

    <p>Из замеченных багофич:</p>
    <ul><li>- Перепрошивка eeprom не сохраняется после рестарта (спасает подмена файла)</li><br />
    <li>- при старте генерит события component_added для всех частей, чего на реальном OC не происходит</li><br />
    <li>- computer.shutdown(true) - не работает</li><br />
    <li>- os.date('!%R') - не работает</li><br />
    <li>- клавиша '~' - генерит событие с неправильным кодом</li><br />
    <li>- события clipboard, drag, drop, scroll не генерятся</li><br />
    

  16. И зачем тебе часы, которые показывают время, которое никакое на самом деле не время? Какое применение, хотя бы, теоретическое, или, эстетическое?

    Как не время? То что оно идет неравномерно относительно нас, ничего не значит. Солнце/луна движутся, день сменяет ночь, внутриигровое время тикает.

    Или на сервере время отсутсвует как класс? о_О

     

    зы

    аж побежал смотреть от любопытства, но не смотря на выданную кирку, застрял на стадии авторизации в лаунчере )


  17. Работа, конечно, не простая. Да и не все функции реализованы. Дорабатывать все равно придется в игре. Реализовал поддержку нескольких экранов, редстоуна, а также тестовую панель для работы с адаптером. Open folder открывает папку с дисками. При первом запуске надо задать конфигурайию, и сохранить ее. Далее будет грузится сама из выбранной папки компьютера.

    Крутотень.

     

    От себя добавлю несколько скринов:

    s_1434655889_6285970_ff11396990.png s_1434655888_9507166_93afd65efe.png s_1434655890_9987277_63c9673cfd.png

     

    Из замеченных багофич:

    • - Перепрошивка eeprom не сохраняется после рестарта (спасает подмена файла)
    • - при старте генерит события component_added для всех частей, чего на реальном OC не происходит
    • - computer.shutdown(true) - не работает
    • - os.date('!%R') - не работает
    • - клавиша '~' - генерит событие с неправильным кодом
    • - события clipboard, drag, drop, scroll не генерятся
    • - редактор форумных постов кривой )
×
×
  • Создать...