Перейти к публикации
Форум - ComputerCraft
NEO

Кэшированный инвентарь робота

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

Хаюшки всем кто читает this тему.

Работа с инвентарём довольно медленная, поиск, сканирование и получение информации, я решил ускорить этот процесс путём кэширования, обработки события inventory_changed, список потенциальных слотов для сканирования, такими являются слоты с количеством айтемов меньше максимального, еще возможна подмена функций всех продвинутых контроллеров инвентаря(функция не опробована), конечно не без минусов, есть такие ситуации которые могут нарушить работу кэша, например, если слот полный но в какой-то момент стал потенциальным, тобишь каким-то образом айтемов стало меньше максимума, увы но на данный момент других способов кроме сканирования слота нет, тут нужно будет кэшу сказать что бы обновил слот.

 

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

Библиотека очень сырая, ей требуется доработок. Была написана за пару часов.

Список функций.

init([advancedMode: boolean]): nil - инициализирует библиотеку, опционально можно включить замену dropIntoSlot, suckFromSlot.
free(): nil - удаляет callbacks с прослушки событий.
scan():nil - сканирует полностью весь инвентарь.
addPotentialSlot(slot:number): nil - добавляет в очередь потенциальный слот.
removePotentialSlot(slot:number): nil - находит и удаляет слот из очереди.
isPotetial(slot:number): nil - проверяет, находится-ли слот в очереди.
update(): nil - сканирует слоты из очереди и заносит в кэш, вызов updateSlot для всей очереди.
updateSlot(slot:number): nil - сканирует слот и заносит в кэш.
getSlot(slot:number): table or nil - извлекает информацию о слоте из кэша.
setSlot(slot:number, item:table): nil - устанавливает информацию о слоте, функция для внутреннего использования.
requestInventorySize(): nil - сканирует размер инвентаря и обновляет информацию для кэша.
getInventorySize(): number - получает закэшированный размер инвентаря.

Остальные функции полностью служебные, обо всех багах или предложениях сообщать сюда.

P.S

Надеюсь она будет полезной как я предполагаю.

 

Ссылка на исходный код: https://github.com/Avaja/OpenComputers/blob/master/cache.lua

Изменено пользователем NEO
исправление ошибки в тексте, добавлена недостающая буква
  • Like 7

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


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

Обновление за 4.03.18

 

Добавлено:

1. requestInventorySize

2. getInventorySize

 

Теперь для сканирования размера требуется использовать requestInventorySize, а для получения из кэша getInventorySize.

Изменено пользователем NEO

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


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

Хаюшки всем кто читает this тему.

Хеллоу all, читающий этот comment. В русском языке too few слов для раскрытия этой темы, поэтому приходится заимствовать английские words.

 

Возникли some вопросы:

 

	if compt.inventory_controller == nil then
		error("inventory_controller not found")
	end
А разве component позволяет такой способ проверки? Насколько я помню, ошибка случится ещё на первой строке этого фрагмента. Для этого даже component.isAvailable придумали.

 

 

Можешь пояснить, что обрабатывается в перехваченных proxy.dropIntoSlot и proxy.suckFromSlot?

			proxy.dropIntoSlot = function(facing, slot, count)
				if count == nil and self.isPotential(slot) then
					self.removePotentialSlot(slot)
					item.setSlot(slot, nil)
				else
					local item = self.getSlot(slot)
					if item.size == count then
						self.setSlot(slot, nil)
					else
						item.size = item.size - count
					end
				end
				return nativeDropIntoSlot(facing, slot, count)
			end
Какой инвентарь анализируется в этом участке кода? Вряд ли инвентарь робота, т.к. номер слота в данном случае не имеет к нему отношения. И вряд ли какой-либо внешний инвентарь, т.к. не учитывается сторона, с которой находится инвентарь.

 

А ещё интересно узнать, почему ты отказался от проверки count==nil и результатов, возвращаемых оригинальными proxy.dropIntoSlot и proxy.suckFromSlot. Разве такой отказ не может привести к рассинхронизации кэша?

  • Like 2

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


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

 

 

Можешь пояснить, что обрабатывается в перехваченных proxy.dropIntoSlot и proxy.suckFromSlot?

Какой инвентарь анализируется в этом участке кода? Вряд ли инвентарь робота, т.к. номер слота в данном случае не имеет к нему отношения. И вряд ли какой-либо внешний инвентарь, т.к. не учитывается сторона, с которой находится инвентарь.

 

А ещё интересно узнать, почему ты отказался от проверки count==nil и результатов, возвращаемых оригинальными proxy.dropIntoSlot и proxy.suckFromSlot. Разве такой отказ не может привести к рассинхронизации кэша?

 

Да, производит, я указал что функции не обкатанные, count == nil как раз обрабатывается, нужно только перед этим выполнить родную функции и по успешному результату - удалить из кэша.

  • Like 1

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


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

Точно. Сам не знаю, куда смотрел.

На самом деле можно много чего ускорить, разного рода получение информации, понятно что родные действия не исправить, но чаще всего робот использует инвентарь - каким можно запоминать действия в памяти, сокращая обращения к родным функция, но тут уже требуется обкатка временем, много всяких особенностей. Есть сложные варианты, например воронка, она изымает из робота без его ведома, надо думать. Главное ориентироваться на сокращение родных вызовов. Первое что приходит в голову - это считать последний айтем в инвентаре потенциальным, но тут нужно сделать отдельный режим "извлечения из вне", ибо такой режим увеличивает время на работу с инвентарём.

Изменено пользователем NEO

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


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

С библиотеками для роботов вообще беда. Именно взаимодействие с миром наиболее затратно по времени, а каждый алгоритм оптимален в рамках ограниченного круга задач. Библиотека, работающая в широком диапазоне условий, как правило, громоздка и сложна в управлении.

 

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

 

Громоздкость библиотек тоже имеет значение. Многие стремятся удешевить роботов, выкинув лишние планки памяти и даже диски, используя загрузку по сети. А универсальные библиотеки почти всегда громоздки.

 

Рассмотрю различия условий оптимизации на примере уже упомянутой навигации. Простой робот-шахтёр обычно движется по кратчайшему маршруту лицом вперед, прорубая себе дорогу. В редких случаях роботу нужен дополнительный алгоритм обхода препятствий или даже выхода из лабиринта, если робот закопался в породу, слишком прочную для его инструмента. Для шахтёра, копающего по данным геосканера, требуется алгоритм построения оптимального маршрута для добычи всех руд. Его алгоритм обхода препятствий отличается тем, что часть препятствий известна до начала движения. А для робота, разносящего ресурсы по обрабатывающим машинкам, требуется минимизировать количество поворотов, при случае использовать движение задом, ни в коем случае не ломать обнаруженные препятствия и даже не пытаться обходить их. Вроде бы все алгоритмы решают задачу навигации, но мне кажется бессмысленным оформлять их в виде единой библиотеки.

 

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

 

Я пришёл к выводу, что на computercraft.ru из библиотек для роботов наиболее полезны те, что содержат минимум кода без избыточных структур данных и интерфейсов, и демонстрируют какой-то интересный подход в решении привычных для роботов задач. Надежда на то, что кто-то использует библиотеку в своей программе, не велика. Зато при описанном выше подходе многие из читателей смогут разобраться в коде и оценить красоту алгоритма, что повысит шансы на обсуждение и генерацию новых идей. Предлагаю рассмотреть именно это направление. Но это IMHO, конечно.

 

Если бы я всё-таки решился писать полноценную библиотеку кэширования инвентаря, то в первую очередь свёл бы к минимуму количество публичных методов, чтобы не смущать пользователя. В идеале хотелось бы один раз задать режим работы инвентаря, а дальше только выдавать пользователю информацию.

 

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

Изменено пользователем eu_tomat
  • Like 4

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


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

....

Согласен, 100%, я её написал за пару часов, а так её нужно еще писать и писать, оформлять, правильные названия дать.

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

Изменено пользователем NEO

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


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

Я для транспозеров делал немного похожее, но проще, т. к. там все операции под контролем.
Для робота перепроверка по кэшу не так сильно нужна, да и не поможет она, если робот наедет на воронку.

У меня есть интересная задачка по управлению инвентарем.
Для геокопалки я написал упаковщик предметов в блоки (алмы, уголь, редстоун и т. д.), изначально все сканировал, предвычислял оптимальное заполнение, но алгоритм вышел очень громоздкий и занимал большую часть прошивки.
Немного подумав, я упростил - сделал сортировку в конец инвентаря, оттуда по одному предмету кидал в область крафта. Вышло компактно, но сортировка и крафт занимают очень много времени, защита от дурака - полный перебор, а после какой-то обновы изменилась механика инвентаря и алгоритм перестал нормально завершаться.

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

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


Ссылка на сообщение
Поделиться на других сайтах
Для геокопалки я написал упаковщик предметов в блоки (алмы, уголь, редстоун и т. д.)

интересная, но бесполезная фича. Тоже сделал давно когда-то еще упаковщик для своей программки титан, которая до сих пор где-то валяется неоформленная  до конца. Миллионы кусочков ляписа напрягали. Но потом понял, что оно того не стоит. Лучше использовать мощные силк-инсты на этапах мид/лейт гейма, а на начальных этапах игры можно и страдать.

Дело в том, что очень часто или моды, или сами админы на серверах фиксят рецепты и уже ляпись и редстоун с углем, или даже слитки собираются правильно и реалистично в блоки только литьем тинкерсов всяких или только строго в компрессорах ИК, грега и типа того, так как оно и положено, а не в сраном ванильном столике по ванильным законам.

То есть писать это('алгоритм вышел очень громоздкий и занимал большую часть прошивки')  можно, и даже нужно но только на свой страх и риск, и учитывать нужно, что эта "громоздкая" фича однажды, а может даже с большой вероятностью, окажется кучкой ненужного бесполезного кода на конкретном сервере, и как минимум нужно в конфиге робота добавить что-то типа разрешитьУпаковку = ложь

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


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

Так и есть: нет верстака - нет упаковки, но это устарело. Я хочу, чтобы программа собиралась под конкретного робота, из конструктора или напрямую из интернета.

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


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

было бы прикольно сделать чёт наподобие СистемыШаблонныхКонструкций

типа ты вводишь что тебе нужно(фермер, шахтёр, шахтёр с геосканером), и пишешь какие апгрейты есть

и он тебе собирает роботапрограмму из готовых кусков

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


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

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×