|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Сохранение и загрузка записи с часто изменяемой структурой
Добрый день.
Мозгую над одной задачей, подумал, может у кого есть опыт в подобных вещах. В приложении есть форма настройки выбранной учетной записи сервиса. На форме несколько контролов разного типа: чекбокс, текстовое поле, поле с выпадающим списком и др. Есть запись, типа: Код:
TConfig = record Name: string[30]; Age: byte; Active: boolean; Obj: array[1..10] of byte; end; Код:
var Config: TConfig; Запись TConfig в моем случае часто меняется и уже достигла более 100 элементов, в том числе массивов со своей структурой. При добавлении нового элемента в структуру записи TConfig: 1. добавляется новый контрол на форму; 2. к этому контролу пишется процедура, которая записывает значение контрола в элемент записи TConfig. 3. в событие показа формы добавляется код, заполняющий значение контрола. При этом есть недостаток - если сохранять запись в типизированный файл (File of TConfig), то при изменении структуры данные из старого файла не читаются. А если преобразовывать запись во что-то вроде XML или подобный формат, то надо еще править процедуры сохранения и загрузки данных. Я попробовал реализовать задачу другим путем - создал свой класс, типа именованного списка, который хранит элементы в формате имя = значение + организовал поддержку иерархической структуры - к элементам добавил ссылку на дочерний элемент и ссылку на следующий элемент этого же уровня; сделал методы навигации по данным. В итоге решилась масса проблем и открылись свои плюсы. Пример записи и чтение данных из объекта-списка. Код:
var Config: TDataBank; Config['Name']:='Василий'; Config['Age']:=5; s:=Config['obj:2.Count']; // 2 элемент массива obj, свойство Count Для заполнения формы и для изменения данных при манипуляции с контролами формы были созданы 2 универсальные процедуры, которые по имени контролов считывают и записывают данные в объекте-списке TDataBank. Поэтому исчезла необходимость под номером 2 и 3 случая использования записи. Так же исчезла проблема с загрузкой: данные считываются по имени, а если какого-то элемента не хватает, то он просто не заполнен. При этом не требуется менять методы сохранения и загрузки. Появилась возможность манипулировать структурой прям в runtime - при присвоении значения по неизвестному имени элемент с этим именем тут же создается в объекте-списке, в том числе массив или дочерний элемент. Вроде все здорово, но появилась своя проблема - в процессе разработки приходится все переменные задавать как строки (Config['Name']) и если была допущена опечатка, то ошибку можно долго искать - IDE не подсказывает что название некорректное и не предлагает варианты названий переменных структуры когда поставишь точку после Config... Приходится работать с текстовым файликом, где хранить описание всех элементов создаваемой структуры. Есть ли у вас какая-либо практика или идеи как можно успешнее решить задачу при условии частого добавления или изменения структуры настроек? |
#2
|
||||
|
||||
А не проще ли использовать готовые компоненты, предназначенные для сохранения/чтения параметров?
|
#3
|
||||
|
||||
Не, правда, зачем такие сложности, можно упростить задачу. Вот когда-то уже отвечал на подобное примером, скопируйте из него к себе содержимое FormCreate и FormDestroy, а дальше попробуйте изменить состояние/содержимое компонентов и перезапустите сборку, мож так проще будет
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Dredfil (17.03.2018)
|
#4
|
|||
|
|||
Спасибо, посмотрю что там.
|
#5
|
|||
|
|||
Цитата:
Интересное решение. Оно подходит, чтобы сохранять и загружать свойства всех контролов формы. Однако, если я пользователю вышлю обновленную программу с новым набором контролов, то у него при запуске подтянется старый ини-файл и затрет все новые контролы, которые я добавил на форму. А если я сам буду высылать ему новый ини-файл, то затрутся свойства контролов, настроенные пользователем. (когда более 100 элементов настройки и более 10 учетных записей перенастраивать очень затруднительно). И вторая проблема это использование в логике программы настроек с этой формы, когда учетных записей 10 или 100. Сейчас при настройке всех учетных записей используется 1 форма: при открытии формы заполняются значения контролов настройками выбранной в данный момент учетной записи. Разве что, держать в памяти созданные формы для каждой учетной записи и для использования настроек конкретной учетной записи в логике программы обращаться к свойствам конкретой формы. Может быть, это решение и не плохое... Но все же остается первая проблема. Последний раз редактировалось Dredfil, 18.03.2018 в 00:12. |
#6
|
|||
|
|||
Цитата:
|
#7
|
||||
|
||||
Цитата:
Цитата:
Цитата:
И видимо главное, здесь наблюдается смешивание понятий относящихся к самой программе и контентом ей создаваемым, такое нужно разносить в пространстве Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#8
|
|||
|
|||
Цитата:
Спасибо за идею! Думаю, ее можно развить в нужном направлении. Сервис работает в многопоточном режиме одновременно со всеми учетными записями: 1 поток - 1 учетка. Настройки, которые вводит пользователь влияют на логику работы потоков. Я часто выпускаю обновления в виде изменения возможных настроек - это можно отнести к метаданным (набор возможных настроек). То, что заполняет пользователь, можно отнести к данным пользователя (состояние набора настроек). А то, чем оперирует сервис помимо настроек, можно отнести к данным сервиса. Т.к. учетные записи не переключаются, а работают в разных потоках одновременно, придется все же создавать несколько экземпляров форм, полагаю. Пока что не совсем понятно как именно при первом запуске обновленной программы сравнивать 2 ини файла (новый мною высланный и старый пользовательский), чтобы определить различия и из старого ини файла заполнить свойства контролов в новом. |
#9
|
||||
|
||||
Цитата:
Код:
[ProgVer] MetaVersion=0.1 Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение: | ||
Dredfil (18.03.2018)
|
#10
|
||||
|
||||
Цитата:
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
Dredfil (18.03.2018)
|
#11
|
|||
|
|||
Получается, надо парсить ини-файлы как обычный текст?
Алгоритм примерно таков: перебираем объекты в старом файле, находим соответствующий объект в новом файле, удаляем целиком секцию в новом файле, заменяя секцией из старого. Все, чего нет в старом файле, в новом останется нетронутым, а все чего нет в новом файле, но есть в старом, не перенесется, т.к. отныне оно не актуально. Плюс создаем отдельные формы на каждую учетную запись и при работе с настройками просто показываем пользователю конкретную форму настроек, а в логике потока через переменную указатель (который заполняем при создании потока) обращаемся к нужной (своей) форме настроек. Блестяще, коллеги! Низкий поклон всем, кто участвовал. |
#12
|
||||
|
||||
Цитата:
|
#13
|
|||
|
|||
Все оказалось еще проще. Не надо выполнять парсинг в тексте.
Алгоритм такой: 1. Создаем временную форму и загружаем в нее форму из файла. 2. Перебираем все компоненты (через Components) на целевой форме и ищем их на временной форме по имени. 3. Если на временной форме компонент найден, то в зависимости от типа компонента, тянем нужные свойства на целевую форму. вот и все )) Всем удачи! |
#14
|
|||
|
|||
Всем привет!
Давно реализовал алгоритм на основании обсуждений в форуме, но как оказалось, этот вариант не подходит. Дело в том что учетных записей много и форма создается для каждой учетной записи. Когда их уже 100, то загрузка форм из файлов занимает чуть больше минуты. Но учеток может быть и 1000 и 2000. Выходит что при старте программы будет происходить загрузка в течение 10-20 минут. Обходной вариант - параллелить загрузку на потоки, но все равно не получится достичь приемлемого времени загрузки. До 5 секунд я считаю загрузка программы приемлемой. Плюс каждя форма жрет по 200 Кб памяти и это еще только менее 10% контролов на форме, которые в итоге планируется разместить. Следовательно, нужно дальше думать, искать решение. Прошу подключиться, кому по силам. |
#15
|
|||
|
|||
М-м-м... а зачем их, формы, создавать при старте? Создавай по мере необходимости. И убивай после закрытия, что бы память не жралась. Все-равно, все формы юзер одновременно открывать не будет. А если будет, то 0.5-1 сек на создание формы при ее открытии рояля не играют, юзер все равно на кнопки медленнее жмет.
|