Far 3 & SettingsControl

Место, где разработчики плагинов могут поделиться своим опытом.
User avatar
artemsen
Posts: 752
Joined: Sun 07 Feb, 2010 08:55
Been thanked: 2 times

Far 3 & SettingsControl

Post by artemsen » Wed 28 Dec, 2011 15:25

Может я чего-то не понимаю, но....
Вызов SettingsControl с командной SCTL_ENUM не выдает ни одной записи - хотя в базе они есть.
Вызов SettingsControl с командной SCTL_DELETE для удаления ветки (код брал из PluginSettings.hpp) ничего не удаляет, хотя возвращает TRUE.

Это еще не реализовано или я туплю? Есть где-нибудь живой пример?

User avatar
t-rex
Страшный и ужасный
Posts: 4899
Joined: Tue 15 Mar, 2005 16:17
Location: Tel-Aviv
Has thanked: 1 time
Contact:

Re: Far 3 & SettingsControl

Post by t-rex » Wed 28 Dec, 2011 15:50

Приведи полный код.

User avatar
artemsen
Posts: 752
Joined: Sun 07 Feb, 2010 08:55
Been thanked: 2 times

Re: Far 3 & SettingsControl

Post by artemsen » Wed 28 Dec, 2011 16:02

Слишком много кода будет - у меня свои обёртки :-)
Примерно так:
SettingsControl(SCTL_CREATE) //< получил HANDLE
SettingsControl(HANDLE, 0 /*root*/, SCTL_ENUM) //< передал обнулённую структуру FarSettingsEnum, получил её же (всё 0)
Могу расписать полностью, но уже не сегодня :-( Хотел DiskMenuEditor до нового года добить - споткнулся в настройках.
По поводу SCTL_DELETE - оно работает если я создал раздел (через SCTL_CREATESUBKEY) и тут же удалил, но стоит перезапустить Фар - ничего не удаляется. Какой-нибудь стандартный плагин работает с подключами?

User avatar
t-rex
Страшный и ужасный
Posts: 4899
Joined: Tue 15 Mar, 2005 16:17
Location: Tel-Aviv
Has thanked: 1 time
Contact:

Re: Far 3 & SettingsControl

Post by t-rex » Wed 28 Dec, 2011 17:26

пока не покажешь весь свой код, говорить не о чём.

User avatar
artemsen
Posts: 752
Joined: Sun 07 Feb, 2010 08:55
Been thanked: 2 times

Re: Far 3 & SettingsControl

Post by artemsen » Thu 29 Dec, 2011 08:00

По идее старая ветка "group" должна удалиться, новая создаться - вместо этого они плодятся.

Code: Select all

void update_settings(const PluginStartupInfo* psi, const GUID* guid)
{
	HANDLE handle = INVALID_HANDLE_VALUE;
	FarSettingsCreate settings = { sizeof(FarSettingsCreate), *guid, handle };
	assert(psi->SettingsControl(INVALID_HANDLE_VALUE, SCTL_CREATE, 0, &settings));
	handle = settings.Handle;

	FarSettingsValue sub = { 0, L"group" };
	int group_id = psi->SettingsControl(handle, SCTL_OPENSUBKEY, 0, &sub);

	FarSettingsValue val_del = { group_id, NULL };	
	assert(psi->SettingsControl(handle, SCTL_DELETE, 0, &val_del));

	FarSettingsValue sub_new = { 0, L"group" };
	assert(psi->SettingsControl(handle, SCTL_CREATESUBKEY, 0, &sub_new));

	psi->SettingsControl(handle, SCTL_FREE, 0, NULL);
}
А вот так уже работает:

Code: Select all

void update_settings(const PluginStartupInfo* psi, const GUID* guid)
{
	HANDLE handle = INVALID_HANDLE_VALUE;
	FarSettingsCreate settings = { sizeof(FarSettingsCreate), *guid, handle };
	assert(psi->SettingsControl(INVALID_HANDLE_VALUE, SCTL_CREATE, 0, &settings));
	handle = settings.Handle;

	FarSettingsValue sub = { 0, L"group" };
	int group_id = psi->SettingsControl(handle, SCTL_OPENSUBKEY, 0, &sub);

	FarSettingsValue val_del = { group_id, NULL };	
	assert(psi->SettingsControl(handle, SCTL_DELETE, 0, &val_del));

///////////////////////////////////////////////
//Переоткроем настройки
	psi->SettingsControl(handle, SCTL_FREE, 0, NULL);
	FarSettingsCreate settings2 = { sizeof(FarSettingsCreate), *guid, handle };
	assert(psi->SettingsControl(INVALID_HANDLE_VALUE, SCTL_CREATE, 0, &settings2));
	handle = settings2.Handle;
//////////////////////////////////////////////

	FarSettingsValue sub_new = { 0, L"group" };
	assert(psi->SettingsControl(handle, SCTL_CREATESUBKEY, 0, &sub_new));

	psi->SettingsControl(handle, SCTL_FREE, 0, NULL);
}

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Thu 12 Feb, 2015 16:46

Столкнулся с проблемой при работе нескольких экземпляров фара.
Если плагин в одном из экземпляров фара сделал SCTL_CREATE, то другие уже ничего записать в базу не могут, даже после того как первый сделает SCTL_FREE.
Причём SettingsControl отрабатывает как ни в чём не бывало, не возвращая ошибок.

Для воспроизведения важно чтобы второй экземпляр выполнил SCTL_CREATE до того, как первый сделает SCTL_FREE.

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Thu 12 Feb, 2015 20:47

Всё то же самое можно воспроизвести в одном экземпляре.

Code: Select all

local F = far.Flags
local Guid = win.Uuid"4EBBEFC8-2084-4B7F-94C0-692CE136894D"
far.FreeSettings()

local S1 = far.CreateSettings(Guid,F.PSL_ROAMING)
local S2 = far.CreateSettings(Guid,F.PSL_ROAMING)
--S1:Set(F.FSSF_ROOT, "test1", F.FST_STRING, "aaa")
S1:Free()
local Value1 = S2:Get(F.FSSF_ROOT, "test1", F.FST_STRING)
S2:Set(F.FSSF_ROOT, "test1", F.FST_STRING, "bbb")
local Value2 = S2:Get(F.FSSF_ROOT, "test1", F.FST_STRING)
S2:Free()

local S3 = far.CreateSettings(Guid,F.PSL_ROAMING)
local Value3 = S3:Get(F.FSSF_ROOT, "test1", F.FST_STRING)
S3:Free()
far.Show(Value1,Value2,Value3)
Наблюдения:
Повторное (вложенное) создание настроек вызывает видимую задержку.
Похоже что в этом случае в памяти создаётся некая пустая база, не связанная с реальной.
После закрытия этих повторных настроек в реальную базу (db файл) ничего не пишется.

http://bugs.farmanager.com/view.php?id=2940

Shmuel
Posts: 5572
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 21 times
Been thanked: 186 times

Far 3 & SettingsControl

Post by Shmuel » Thu 12 Feb, 2015 21:05

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

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Thu 12 Feb, 2015 21:08

Полагаю не ошибаетесь, но в данном случае этого не происходит: после S2:Free() я ведь для того и переоткрываю базу в третий раз, чтобы убедиться что ничего не записалось.

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Thu 12 Feb, 2015 23:05

И возвращаясь к проблемах SCTL_DELETE (именно с этого тема началась в 2011).
  • В Энциклопедии сказано: SCTL_DELETE Удалить подключ или значение.
    В реальности подключ нельзя удалить просто указав его имя.
    В changelog есть пояснение:
    http://bugs.farmanager.com/view.php?id=2939
  • В энциклопедии сказано: Функция при неудаче вернёт FALSE.
    В реальности функция возвращает TRUE всегда, даже в случае если указанного элемента не существует.
    В том числе, если попытаться удалить подключ по его имени: он конечно не удалится, но функция всё равно вернёт TRUE
    http://bugs.farmanager.com/view.php?id=2938

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Wed 07 Nov, 2018 10:05

Code: Select all

drkns 06.11.2018 20:35:22 +0000 - build 5304

1. Переделана работа с SQLite: теперь при неудаче вместо возврата false или кодов ошибок (которые мы почти нигде не проверяли)
   бросаются исключения. Они пока что перехватываются при открытии db (из-за всего сопутствующего этому процессу шаманства)
   и создании экземпляра настроек плагина (по понятным причинам), т.е. SCTL_CREATE, как и обещано, вернет FALSE в случае неудачи.
   Это должно заодно починить 0002940: SCTL_CREATE: проблемы при создании более одного экземпляра настроек.
   В остальном коде эти возможные исключения (пока) никак не обрабатываются, так что если у вас что пойдет не так - вы об этом узнаете.
   SQLITE_BUSY обрабатывается отдельно - после 5-секундного таймаута будет возможность повторить либо прервать операцию.

   Иными словами - изменения весьма экспериментальные, возможно всякое.

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Wed 07 Nov, 2018 10:11

Code: Select all

Это должно заодно починить 0002940: SCTL_CREATE: проблемы при создании более одного экземпляра настроек.
Теперь при попытке создать второй экземпляр настроек плагина после 5-секундной паузы получаем диалог.

Code: Select all

╔═════════════════════════════════ Error ══════════════════════════════════╗
║ C:\Apps\Far3\Profile\PluginsData\4EBBEFC8-2084-4B7F-94C0-692CE136894D.db ║
║                             Database is busy                             ║
╟──────────────────────────────────────────────────────────────────────────╢
║                           { Retry } [ Abort ]                            ║
╚══════════════════════════════════════════════════════════════════════════╝
Retry ничего не даёт, по Abort возвращается false.

В принципе, всё хорошо. Но предлагаю уменьшить таймаут.

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Wed 07 Nov, 2018 11:25

Сказано:
https://api.farmanager.com/ru/service_functions/settingscontrol.html#SCTL_OPENSUBKEY wrote:SCTL_OPENSUBKEY Открыть существующий ключ настроек.
В реальности успешно открывается и несуществующий ключ.


Предлагаю возвращать ошибку (либо скорректировать документацию, если в пользу текущего поведения есть аргументы).

Update:
https://bugs.farmanager.com/view.php?id=3672
Last edited by John Doe on Fri 09 Nov, 2018 10:09, edited 1 time in total.

User avatar
DrKnS
Posts: 5002
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 166 times

Far 3 & SettingsControl

Post by DrKnS » Wed 07 Nov, 2018 13:31

John Doe wrote:
Wed 07 Nov, 2018 10:11
предлагаю уменьшить таймаут
Этот диалог - busy handler, его основное предназначение - разрешение конфликтов при записи (из разных процессов).
В текущей имплементации этот хендлер ждёт 500 мс и пробует снова, и так 10 раз, потом сдаётся и показывает диалог.
С моей точки зрения такой таймаут вполне уместен при работе с файловой системой.
В реальных сценариях конкурентной записи, скорее всего, будет достаточно одного-двух повторов и задержка вряд ли будет более секунды.

Ваш случай - это исключение, повторы там ничего не дадут по определению.
Т.к. это заведомо неподдерживаемый сценарий, обречённый на неудачу, я не вижу проблемы в том, что автор этого сценария подождёт 5 секунд.

User avatar
zg
zero-gravity
Posts: 5507
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 73 times
Contact:

Far 3 & SettingsControl

Post by zg » Wed 07 Nov, 2018 13:44

John Doe wrote:
Wed 07 Nov, 2018 11:25
если в пользу текущего поведения есть аргументы.
скорость.

User avatar
John Doe
Бюрократ
Posts: 11970
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 133 times

Far 3 & SettingsControl

Post by John Doe » Wed 07 Nov, 2018 13:53

DrKnS wrote:
Wed 07 Nov, 2018 13:31
Т.к. это заведомо неподдерживаемый сценарий, обречённый на неудачу, я не вижу проблемы в том, что автор этого сценария подождёт 5 секунд.
Тут конечно, имел в виду другие сценарии: если двух повторов оказалось недостаточно, то уже есть основания заподозрить, что что-то не по назначению используется (даже если с третьей попытки и получилось бы).

Ну вам виднее, я только предложил.

Post Reply

Return to “Разработка плагинов”