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

Часы OpenComputers (RealTime and GameTime)

Рекомендуемые сообщения

Решил я сделать простые часы для декора. С реальным временем и с игровым.
В итоге недолго почесав репу я сделал небольшую программу для Lua Bios на несколько мониторов (Копипаст но все же )
Получилась вот такая дребедень:
 

 

 

Снизу показывается время игры а сверху реальное время. Время я получаю по tmp файлу записанного в оперативку.
Требования к компу минимальные. Любая видюха, одна плашка памяти, процессор и сам биос с программой.
 Вот сам код:

Скрытый текст

TimeZone выбирает часовой пояс который вы хотите.


--pastebin run tqaNepSZ
local fs = component.proxy(computer.tmpAddress())
local gpu = component.proxy(component.list("gpu")())
local screens = component.list('screen')

local SLEEP_TIME = 0 --Время перед обновлением экрана
local TIME_ZONE = 0 -- Добавляем часы
local t_correction = TIME_ZONE * 3600 


--https://oc.cil.li/topic/1596-multi-screenscreen-mirroring/
local vgpu = {}
setmetatable(vgpu, vgpu)
vgpu.bind = gpu.bind
function vgpu.__index(self, key)
  local setter = { copy = true; fill = true}
  if key:find('set') or setter[key] then
    return function(...)
      for addr in pairs(screens) do
        self.bind(addr,false)
        gpu[key](...)
      end
    end
  else
    return function(...)
      local res = {}
      for addr in pairs(screens) do
        self.bind(addr,false) --Биндим без сброса иначе экран будет прыгать
        local r = {gpu[key](...)}
        res[addr] = #r == 1 and r[1] or r
      end
      return res
    end
  end
end



function os.sleep(timeout)
    checkArg(1, timeout, "number", "nil")
    local deadline = computer.uptime() + (timeout or 0)
    repeat
      computer.pullSignal(deadline - computer.uptime())
    until computer.uptime() >= deadline
  end

function floor_to_step(what,step)
    return math.floor(what/step) * step
end

local function getRealTime()
  local handel = fs.open("/time", "w")
  fs.close(handel)
  local timestamp = fs.lastModified("/time") / 1000 + t_correction
	return os.date("%H:%M:%S %d.%m.%Y", timestamp)
end

local function getMinecraftTime()
    local timestamp = os.time()
    year = tostring(tonumber(os.date("%Y",timestamp))-1970)
    if string.len(year) < 3 then
        for i=1,4-string.len(year) do
            year="0"..year
        end
    end
    return os.date("%H:%M:%S %d.%m.", timestamp)..year
end

max = 10
while true do
realtime = getRealTime()
gametime = getMinecraftTime()
if string.len(realtime) > string.len(gametime) then
    vgpu.setResolution(string.len(realtime),2)
    max = 
    vgpu.setResolution(max,2)
else
    vgpu.setResolution(string.len(gametime),2)
end
vgpu.set(1,1,realtime)
vgpu.set(1,2,gametime)
os.sleep(SLEEP_TIME) --Сон как хотим так и настроем
end

 

Надеюсь кому то как декор зайдут...

Изменено пользователем Taruu
Исправил код еще раз

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@Taruu А почему эти часы не уходят с сон хотя бы на тик? Чем оправдана такая нагрузка на сервер?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
7 минут назад, eu_tomat сказал:

@Taruu А почему эти часы не уходят с сон хотя бы на тик? Чем оправдана такая нагрузка на сервер?

Хм. Не доглядел. Хотя функцию для таймера я давно добавлял (прогу просто давно уже написал)
Смотря на то как он обновляет экраны он ели ели успевает в секунду.

Но а так то наверно все же стоит мне прикрутить переменную на задержку.... Между обновлениями экранов...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
16 минут назад, Taruu сказал:

Смотря на то как он обновляет экраны он ели ели успевает в секунду.

Без задержки эти часы будут пытаться обновить показания с частотой около 120 раз в секунду. А сервер сможет обновить картинку на мониторе с частотой не более 20 раз в секунду. Значит, добавив задержку всего в один тик, можно без заметного ухудшения снизить нагрузку на сервер в 6 раз. Да и 20 раз в секунду нет особого смысла обновлять часы. Уже при частоте около 4 раз в секунду обновление перестаёт играть заметную роль.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 минуты назад, eu_tomat сказал:

Без задержки эти часы будут пытаться обновить показания с частотой около 120 раз в секунду. А сервер сможет обновить картинку на мониторе с частотой не более 20 раз в секунду. Значит, добавив задержку всего в один тик, можно без заметного ухудшения снизить нагрузку на сервер в 6 раз. Да и 20 раз в секунду нет особого смысла обновлять часы. Уже при частоте около 4 раз в секунду обновление перестаёт играть заметную роль.

У меня есть код где один экран и его обновление на миллисекунды работает нормально...
Можно мне умный текст где все эти механики описаны? Буду очень признателен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, Taruu сказал:

Можно мне умный текст где все эти механики описаны?

Какие именно механики?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, eu_tomat сказал:

Какие именно механики?

C тактированием компов. И обновления их элементов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 минуты назад, Taruu сказал:

C тактированием компов. И обновления их элементов.

Стандартная частота обновления объектов в Майнкрафте составляет 20 тиков в секунду. А про бюджеты вызовов недавно писал @Fingercomp в своём блоге: Прямые и кривые методы компонентов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
18 часов назад, Taruu сказал:

Снизу показывается время игры а сверху реальное время. Время я получаю по tmp файлу записанного в оперативку.

К слову, computer.tmpAddress() - независимое от озу хранилище. Самое забавное, что если компьютер перезагружается "мягко" - через computer.shutdown(true), то содержимое даже не очищается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
12 часа назад, Taruu сказал:

Смотря на то как он обновляет экраны он ели ели успевает в секунду.

В программе присутствует ошибка. Из-за неё 96% попыток обновлений времени являются холостыми, и поэтому фактические обновления происходят со средней частотой примерно 4 раза в секунду. При этом интервалы обновления неравномерны, они заданы случайными факторами.

 

15 часов назад, Taruu сказал:

local function getRealTime()
	local handle = fs.open("/time", "w")
	local timestamp = fs.lastModified("/time") / 1000 + t_correction
	return os.date("%H:%M:%S %d.%m.%Y", timestamp)
end

 

Если не закрывать открытый файл, то последующие попытки его открытия будут безуспешными до тех пор, пока файл не будет закрыт сборщиком мусора.

 

Закрытие файла + задержка между обновлениями в 1/4 секунды дадут гораздо более приятный глазу эффект. И нагрузка на сервер снизится раз в 30.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 часа назад, eu_tomat сказал:

В программе присутствует ошибка. Из-за неё 96% попыток обновлений времени являются холостыми, и поэтому фактические обновления происходят со средней частотой примерно 4 раза в секунду. При этом интервалы обновления неравномерны, они заданы случайными факторами.

 

Если не закрывать открытый файл, то последующие попытки его открытия будут безуспешными до тех пор, пока файл не будет закрыт сборщиком мусора.

 

Закрытие файла + задержка между обновлениями в 1/4 секунды дадут гораздо более приятный глазу эффект. И нагрузка на сервер снизится раз в 30.

Когда освобожусь поправлю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Исправил код вроде теперь все правильно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
13 часа назад, Taruu сказал:

Исправил код вроде теперь все правильно...

Не совсем. Так файл не закроется. Вот API для компонента Filesystem. Можно закрывать, например, таким кодом:

fs.close(fs.open("/time", "w"))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
22 часа назад, eu_tomat сказал:

Не совсем. Так файл не закроется. Вот API для компонента Filesystem. Можно закрывать, например, таким кодом:


fs.close(fs.open("/time", "w"))

 

хм сейчас проверю

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


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