У меня работает несколько роботов с выводом данных каждый в свою таблицу. Возникла необходимость сделать сводную таблицу для всех. Пока не понимаю как передавать данные из скрипта в скрипт. Вернее одно решение есть - отдавать через сохраняемый и затем читаемый файл, но во первых это криво, во вторых медленно. Буду благодарен за рабочую идею.
Пользователь
Сообщений: Регистрация: 30.01.2015
16.01.2021 12:53:11
Передайте один раз через файл номер окна. Имея номер окна, можно писать в него из любых скриптов.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 03.03.2016
16.01.2021 12:58:34
Цитата
написал: Передайте один раз через файл номер окна. Имея номер окна, можно писать в него из любых скриптов.
Вы имеете ввиду идентификатор таблицы создаваемый CreateTable() ? Логично, но все равно через файл (
Пользователь
Сообщений: Регистрация: 03.03.2016
16.01.2021 13:03:47
Опять же скрипты роботов должны постоянно проверять этот файл не сменился ли идентификатор в связи с перезапуском скрипта таблицы. Гемор с постоянным обращением к диску.
Пользователь
Сообщений: Регистрация: 03.03.2016
16.01.2021 13:23:42
Хотя...если проверять при помощи IsWindowClosed() и обращаться к файлу в случае получения true, то вроде рабочий вариант. Спасибо.
Пользователь
Сообщений: Регистрация: 27.01.2017
16.01.2021 13:27:53
Вариант 1. in memory database. Самая простая - sqlite3 Вариант 2. Библиотеки обмена: раз - StaticVar от swerg два - luashare от toxa
Вариант 3 - файлы. Но взаимные блокировки будет проблемой.
Вариант 4 - socket. Да, поднять свой socket server и обмениваться.
Вариант 5. Named Pipes. пишем библиотку клиента и сервера.
Пользователь
Сообщений: Регистрация: 27.01.2017
16.01.2021 13:30:32
Правда если только вывод в таблицу, то да, надо знать только id окна.
Пользователь
Сообщений: Регистрация: 25.09.2020
16.01.2021 13:37:46
Kolossi, Подкидываю идею: объединить "несколько роботов" в один и не мучиться.
Ну, а если не хочется, то есть только два способа: через файл и через ОЗУ двойного доступа (для Lua нереально). Поэтому (если s_mike прав) пусть ГЛАВНЫЙ скрипт, запускаемый первым, создаёт эту общую таблицу, записывает её ID в файл, а остальные читают при запуске. А скрипты могут ничего не проверять, если "главный скрипт" по выходу убьёт их всех (правда, я не знаю как это сделать и можно ли сделать вообще).
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
16.01.2021 15:29:59
Цитата
s_mike@rambler.ru написал: Имея номер окна, можно писать в него из любых скриптов.
Не знаю, может у меня версия квика какая-то другая. Но нумерация окон не сквозная, у каждого скрипта своя, начинающаяся с 1. Т.е., идентификаторы окон разных скриптов могут совпадать. И писать в окно другого скрипта не получается.
Надо делать так, как надо. А как не надо - делать не надо.
написал: Имея номер окна, можно писать в него из любых скриптов.
Не знаю, может у меня версия квика какая-то другая. Но нумерация окон не сквозная, у каждого скрипта своя, начинающаяся с 1. Т.е., идентификаторы окон разных скриптов могут совпадать. И писать в окно другого скрипта не получается.
Ндааа, полил холодной водичкой (((
Пользователь
Сообщений: Регистрация: 03.03.2016
16.01.2021 16:18:21
Однако сейчас проверил. Номер окна выдает каждый раз следующий. 16-17-18-19... и так по порядку каждый раз при убиении и запуске скрипта.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
16.01.2021 16:24:47
Цитата
Kolossi написал: Номер окна выдает каждый раз следующий.16-17-18-19... и так по порядку каждый раз при убиении и запуске скрипта.
Так и есть. При перезапуске скрипта идентификаторы новых окон увеличиваются.
Цитата
Nikolay написал: Вариант 3 - файлы. Но взаимные блокировки будет проблемой.
Вот пример организации обмена с двумя файлами: 1-й файл для передачи данных, 2-й - пустой файл, служит флагом для индикации готовности данных к считыванию.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 03.03.2016
16.01.2021 16:36:19
Проверил. Нумерация окон меняется конкретно для каждого скрипта-увеличивается с каждым перезапуском начиная с запуска Квика. Запустив два одинаковых скрипта при помощи перезапусков легко получил окна с одинаковыми идентификаторами. Облом.
Пользователь
Сообщений: Регистрация: 03.03.2016
16.01.2021 16:46:11
Цитата
Старатель написал: Вот пример организации обмена с двумя файлами: 1-й файл для передачи данных, 2-й - пустой файл, служит флагом для индикации готовности данных к считыванию.
И я плавно приехал от идеи общей таблицы к необходимости замены hdd на ssd
Пользователь
Сообщений: Регистрация: 27.01.2017
16.01.2021 16:58:36
Цитата
Старатель написал: Вот пример организации обмена с двумя файлами: 1-й файл для передачи данных, 2-й - пустой файл, служит флагом для индикации готовности данных к считыванию.
Это надо для каждый пары источник-приемник создавать пару файлов. Как только несколько писателей, с двумя файлами может быть блокировка. А приемник должен псевдо-асинхронно это читать.
Пользователь
Сообщений: Регистрация: 30.01.2015
16.01.2021 17:27:32
Цитата
Kolossi написал: Проверил. Нумерация окон меняется конкретно для каждого скрипта-увеличивается с каждым перезапуском начиная с запуска Квика. Запустив два одинаковых скрипта при помощи перезапусков легко получил окна с одинаковыми идентификаторами. Облом.
жаль. Не сработало.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
16.01.2021 17:47:45
Цитата
Nikolay написал: Это надо для каждый пары источник-приемник создавать пару файлов. Как только несколько писателей, с двумя файлами может быть блокировка.
Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна. Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи. Т.е. организуются синхронные запись/чтение.
Кстати, ни разу не видел, блокировок файлов, одновременно открытых несколькими Lua-скриптами. Если файл открыт другим приложением, то, да, было.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 27.01.2017
16.01.2021 17:54:45
Цитата
Старатель написал: Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна. Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи. Т.е. организуются синхронные запись/чтение.
Кстати, ни разу не видел, блокировок файлов, одновременно открытых несколькими Lua-скриптами. Если файл открыт другим приложением, то, да, было.
Блокировки видел, хоть lua и очень быстр в части работы с файлами. Если пара одна, то это приведет к тому, что все будут ждать пока он освободится. А если несколько, то приемник сможет переключаться между парами, чтобы не ждать.
Конечно, все это для обмена большими объемами и несколькими источниками-потребителями. Если данных мало и они редки, то все это излишне.
написал: Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна. Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи. Т.е. организуются синхронные запись/чтение.
Кстати, ни разу не видел, блокировок файлов, одновременно открытых несколькими Lua-скриптами. Если файл открыт другим приложением, то, да, было.
Блокировки видел, хоть lua и очень быстр в части работы с файлами. Если пара одна, то это приведет к тому, что все будут ждать пока он освободится. А если несколько, то приемник сможет переключаться между парами, чтобы не ждать.
Конечно, все это для обмена большими объемами и несколькими источниками-потребителями. Если данных мало и они редки, то все это излишне.
lua открывает файлы в разделяемом режиме. Поэтому блокировок не бывает. Файл нужно просто читать и проверять целостность данных.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 27.01.2017
16.01.2021 18:24:17
Для чтения. Записать одновременно в один файл с двух сторон, то еще занятие. Да, файл-флаг здесь решит проблему, чтоб все ждали пока он есть. А когда его нет, то все писатели одновременно ринутся писать в один тот-же файл.
Если источник-приемник один, то достаточно в источнике открыть файл в режиме записи, а в приемнике в режиме чтения и просто проверять новые данные в этом файле через read("*l"). Писатель записал, читатель их прочитал. Скрипт индикатору может спокойно так передавать информацию.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
16.01.2021 18:29:46
Цитата
Nikolay написал: Конечно, все это для обмена большими объемами и несколькими источниками-потребителями. Если данных мало и они редки, то все это излишне.
ТС задал вопрос по выводу данных в общую визуальную таблицу. Врядли там большие объёмы данных.
Цитата
Nikolay написал: Если пара одна, то это приведет к тому, что все будут ждать пока он освободится.
А в других перечисленных вами вариантах ждать не будут?
Цитата
Nikolay написал: Если источник-приемник один, то достаточно в источнике открыть файл в режиме записи, а в приемнике в режиме чтения и просто проверять новые данные в этом файле через read("*l").
Можно и так. Тогда отпадает необходимость в открытии/зактытии/удалении файлов, что затратно.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Второй файл как раз служит для писателей индикатором, что первый файл занят, и запись не возможна.Как только приёмник прочитает данные, он удаляет 2-й файл, что сигнализирует о возможности записи.Т.е. организуются синхронные запись/чтение.
Я делаю так же, только с одним файлом. Передатчик создает файл и пишет туда инфу. Приемник смотрит наличие этого файла. Для него это флаг, что можно читать свежую инфу. Он (приемник) ее читает и удаляет файл. Для передатчика отсутствие файла означает, что файл прочитан и можно создавать файл для передачи новой инфы. Если это и хуже варианта с двумя файлами, то интересно чем?
Пользователь
Сообщений: Регистрация: 25.09.2020
16.01.2021 18:58:36
Игорь Б, По условию там вроде как МНОЖЕСТВО скриптов, и все они должны ПИСАТЬ, готовя сводную таблицу. Я вижу такое решение файл - один, но для каждого скрипта выделяется собственное пространство (фиксированного объёма). Далее они читают и пишут только в свои зоны, а общий диспетчер (который эту таблицу формирует) ставит флаги "прочитано, можно писать следующую порцию". В любом случае, работа множества скриптов с обменом информацией через файл есть геморрой.
Пользователь
Сообщений: Регистрация: 27.01.2017
16.01.2021 19:21:18
Цитата
А в других перечисленных вами вариантах ждать не будут?
Так смотря что ждать. Если база данных, то смотрим какой уровень изоляции транзакции оная поддерживает. Можно сделать несколько таблиц для каждой пары (примерно как и с файлами). Писатель блокирует таблицу, другие таблицы доступны. Читатель читает те таблицы, что доступны.
Если библиотеки обмена, то их авторы доступны.
Если socket, то он по умолчанию блокирующий. Т.е. надо ждать. В книге Роберту Иерузалимски. «Программирование на языке Lua» есть пример Невытесняющая многонитевость.
named pipes позволяют сделать многопоточное подключение, к серверу. Хотя именованные каналы - это по сути файлы, только в памяти.
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
16.01.2021 21:31:47
Цитата
Kolossi написал: Проверил. Нумерация окон меняется конкретно для каждого скрипта-увеличивается с каждым перезапуском начиная с запуска Квика. Запустив два одинаковых скрипта при помощи перезапусков легко получил окна с одинаковыми идентификаторами. Облом.
Один скрипт выводит все таблицы, включая "сводную", другой кидает ему данные через
Цитата
Nikolay написал: Библиотеки обмена: раз - StaticVar от swerg два - luashare от toxa
Ну или даже один скрипт выводит сводную таблицы, остальные ему кидают данные через указанные механизмы.
написал: Если источник-приемник один, то достаточно в источнике открыть файл в режиме записи, а в приемнике в режиме чтения и просто проверять новые данные в этом файле через read("*l").
Можно и так. Тогда отпадает необходимость в открытии/зактытии/удалении файлов, что затратно.
При частой записи данных файл обмена может сильно разрастись. В этом случае есть сомнения в скорости сброса данных на диск. Маленькие файлы кешируются в памяти операционной системой, а большие? Не получится ли так, что каждый новый flush будет дольше предыдущего?
Цитата
Игорь Б написал: Я делаю так же, только с одним файлом. Передатчик создает файл и пишет туда инфу. Приемник смотрит наличие этого файла. Для него это флаг, что можно читать свежую инфу. Он (приемник) ее читает и удаляет файл. Для передатчика отсутствие файла означает, что файл прочитан и можно создавать файл для передачи новой инфы. Если это и хуже варианта с двумя файлами, то интересно чем?
Думаю, не хуже. Но в обоих случаях при одновременном открытии файла обмена несколькими источниками гипотетически часть данных может быть потеряна.
Цитата
Владимир написал: файл - один, но для каждого скрипта выделяется собственное пространство (фиксированного объёма). Далее они читают и пишут только в свои зоны, а общий диспетчер (который эту таблицу формирует) ставит флаги "прочитано, можно писать следующую порцию".
Вариант, заслуживающий внимания.
Ещё вариант: читать/писать под локом. Файл один, открывается один раз, при остановке скрипта закрывается. Данные записываются в режиме изменения в начало файла, сообщение добивается нулями до фиксированной длины.
Надо делать так, как надо. А как не надо - делать не надо.
Один скрипт выводит все таблицы, включая "сводную", другой кидает ему данные через
Цитата
написал: Библиотеки обмена: раз - StaticVar от swerg два - luashare от toxa
Ну или даже один скрипт выводит сводную таблицы, остальные ему кидают данные через указанные механизмы.
Спасибо, буду пробовать.
Пользователь
Сообщений: Регистрация: 03.03.2016
17.01.2021 09:26:05
Swerg огромное спасибо за библиотеку !!! Все работает как хотелось. Дальше дело техники - передать цветовые коды и тп.
К сожалению часть таблиц, которые хотелось бы вынести в общие, обрабатывают мышинный callback и решения как его отдать из скрипта общей таблицы роботу с созданием параллельного потока я не вижу.
Ну и ладно, и так хорошо. Еще раз спасибо.
Пользователь
Сообщений: Регистрация: 27.01.2017
17.01.2021 10:41:21
Если у Вас ячейки привязаны к конкретному скрипту (т.е. реакция на нее однозначно для скрипта №2), особой разницы нет, где событие прошло. Делаете очередь событий и передаете события с параметрами обратно в скрипт через тот же механизм. А скрипт уже, в свою очередь, опрашивает на предмет нового события из своей области обмена.
Пользователь
Сообщений: Регистрация: 25.09.2020
17.01.2021 14:11:29
Nikolay, Оба-на! Я когда-то занимался диалоговыми программами, и у меня всегда имело ОГРОМНОЕ значение, где событие прошло! В частности, обработчики событий в главном и контекстном меню моего скрипта совершенно разные. Кроме того, "очередь событий" автоматически делает невозможной иметь объект реакции типа "группа событий", что накладывает просто крест на хоть сколько-нибудь сложном диалоге. Наконец, обмен событиями между скриптами (тем более, на Lua) - это идеологический маразм, это не будет работать НИКОГДА! В крайнем (и далеко не лучшем ) случае это будет служить ВЕЧНЫМ источником глюков. А глюков в Lua и без того более, чем достаточно.
Пользователь
Сообщений: Регистрация: 27.01.2017
17.01.2021 15:02:08
Раз необходимо иметь разные события для разных окон, то дайте имена этим событиям разные или сопровождайте их разным наборов параметров, чтобы обработчик понимал с чем имеет дело.
А что касается интерфейса, то он может быть расположен на устройстве на Марсе. А сервер должен получить события, что пользователь инициировал и как-то прореагировать: ракету запустить или вернуть ответ в тот же интерфейс. Интерфейс и сервер (обработчик и т.д.) это не обязательно единое целое.
Что касается групп событий, то здесь надо формализовать как эта группа формируется. Возможно на клиенте с интерфейсом надо сгруппировать по какому-то признаку и уже передать эту группу в очередь как единое целое.
Пользователь
Сообщений: Регистрация: 25.09.2020
17.01.2021 15:09:34
Nikolay, Лично у меня интерфейс с сервером отсутствует как класс. Интерфейс с Квиком ужат до предела, до пары-тройки утилит. А интерфейс с юзером имеет все возможности, которые вообще можно выжать из чистого Lua.
Да как угодно "эта группа формируется"! Объект реакции на событие типа "группа событий" не может быть втиснут в очередь событий - здесь требуется именно стек очередей, поскольку все объекты этой очереди должны быть обработаны "вне очереди".
Пользователь
Сообщений: Регистрация: 03.03.2016
17.01.2021 21:10:15
Цитата
Nikolay написал: Если у Вас ячейки привязаны к конкретному скрипту (т.е. реакция на нее однозначно для скрипта №2), особой разницы нет, где событие прошло. Делаете очередь событий и передаете события с параметрами обратно в скрипт через тот же механизм. А скрипт уже, в свою очередь, опрашивает на предмет нового события из своей области обмена.
Легко давать советы не особенно вникая.) Передать колбэк не проблема только вот что бы принять его другим скриптом механизма прерывания и включения параллельного потока нет. Или вы предлагаете main() в цикле опрашивать переменную на случай наступления события?
Пользователь
Сообщений: Регистрация: 27.03.2016
17.01.2021 22:34:37
Kolossi, возможно, подойдет вариант
У меня он когда-то работал.. Без цикла вообще.
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
18.01.2021 08:30:08
Цитата
Kolossi написал: Swerg огромное спасибо за библиотеку !!!
Рад, если помогло. Обращайтесь :)
Пользователь
Сообщений: Регистрация: 27.01.2017
18.01.2021 10:02:25
Цитата
Легко давать советы не особенно вникая.) Передать колбэк не проблема только вот что бы принять его другим скриптом механизма прерывания и включения параллельного потока нет. Или вы предлагаете main() в цикле опрашивать переменную на случай наступления события?
Да, опрашивать по изменению количества в очереди. Собственно, это не такая и редка задача: Квик исполнитель, а интерфейс может быть в базе данных, на таблицах. Ясно, что лучше написать прямую библиотеку, но раз ее нет, надо передавать команды по каналам связи.
Легко давать советы не особенно вникая.) Передать колбэк не проблема только вот что бы принять его другим скриптом механизма прерывания и включения параллельного потока нет. Или вы предлагаете main() в цикле опрашивать переменную на случай наступления события?
Да, опрашивать по изменению количества в очереди. Собственно, это не такая и редка задача: Квик исполнитель, а интерфейс может быть в базе данных, на таблицах. Ясно, что лучше написать прямую библиотеку, но раз ее нет, надо передавать команды по каналам связи.
Попробую объяснить на пальцах. В скрипте робота есть таблица в которой по дабл-клик на ячейку меняется значение некоторой переменной. Таблица перенесена в другой скрипт. Что дальше? Никаких проблем нет с обработкой клика и передачи этого события в первый скрипт в виде изменения содержимого общей для двух скриптов переменной. Вопрос как ее получить в первом скрипте? Постоянно опрашивая изменение в цикле? Это значит, что в определенном месте обработки скрипта. Замечу, что в первом случае это обрабатывается в параллельном потоке.
Пользователь
Сообщений: Регистрация: 27.01.2017
18.01.2021 14:38:09
Скрипт с таблицей имеет очередь передачи сообщений - она же таблица в staticVаr, допустим. При возникновении события в таблице в эту очередь записывается информация. Как Вы и написали проблем с передачей нет.
Другой скрип, смотрит на эту очередь и читает информацию, если в ней что-то появилось. Опрашивать, допустим по увеличению размера. Не такая и проблема выполнить что-то типа: last_count < #Table
На самом деле, даже если это один скрипт, некоторые команды нежелательно исполнять в колбеке таблицы. А значит их надо передавать в дополнительный поток скрипта, через любую переменную видимого контекста. Это мало отличается от схемы с разделяемой переменной. Неэффективность будет только в том, что все события пойдут через очередь.