Приветствую.
Наверное, не раз вам хотелось, чтобы пользовательские индикаторы запоминали свои последние настройки, так, как это делают стандартные индикаторы.
Наверное многим разработчикам, ориентированным на кодобазу и массового пользователя хотелось сделать поддержку нескольких языков.
Как это выглядит для пользователя:
Так вот, это реализуемо. Правда реализация не на пальцах, а путем мутации кода.
Для разработчика все немного сложнее.
Как я уже сказал, подобный функционал возможен исключительно благодаря изменениям исходного кода скрипта. Никакой другой способ не в состоянии дать тот же результат. Другими словами, скрипт меняет сам себя, или мутирует.
На самом деле все не так страшно.
Вот так выглядит код скрипта, представленного на видео:
#property show_inputs bool IsEnglish = /*--!1*/false/*/--!1*/; /*--!2*//*/--!2*/ string Text.Description = "in English"; /*--!3*//*/--!3*/ bool Switch.Language = false; /*--!4*//*/--!4*/ string String = /*--!12*/"123"/*/--!12*/; /*--!5*//*/--!5*/ double Double = /*--!13*/0.00000000/*/--!13*/; /*--!6*//*/--!6*/ bool Bool = /*--!14*/false/*/--!14*/; /*--!7*/extern/*/--!7*/ string Текстовое.Описание = "на русском"; /*--!8*/extern/*/--!8*/ bool Переключить.Язык = false; /*--!9*/extern/*/--!9*/ string Строка = /*--!12*/"123"/*/--!12*/; /*--!10*/extern/*/--!10*/ double Вещественное = /*--!13*/0.00000000/*/--!13*/; /*--!11*/extern/*/--!11*/ bool Булево = /*--!14*/false/*/--!14*/; #include <Mutate.mqh> int init() { MutateInit(true, false, "experts/scripts/", "MutableLanguage", ".mq4", ".ex4"); if (!IsEnglish) { String = Строка; Double = Вещественное; Bool = Булево; Switch.Language = Переключить.Язык; } if (Switch.Language) { IsEnglish = !IsEnglish; } MutateAddBool(1, IsEnglish); if (IsEnglish) { MutateAddText(2, "extern"); MutateAddText(3, "extern"); MutateAddText(4, "extern"); MutateAddText(5, "extern"); MutateAddText(6, "extern"); MutateAddText(7, ""); MutateAddText(8, ""); MutateAddText(9, ""); MutateAddText(10, ""); MutateAddText(11, ""); } else { MutateAddText(2, ""); MutateAddText(3, ""); MutateAddText(4, ""); MutateAddText(5, ""); MutateAddText(6, ""); MutateAddText(7, "extern"); MutateAddText(8, "extern"); MutateAddText(9, "extern"); MutateAddText(10, "extern"); MutateAddText(11, "extern"); } MutateAddString(12, String); MutateAddDouble(13, Double); MutateAddBool(14, Bool); Mutate(); } int start() { return(0); }
Как видите, код несложен, правда самое интересное запрятано в библиотеке, а в коде чистое и незамутненное управление мутацией. Немного о принципе.
Мутирующий код облачен в теги:
bool IsEnglish = /*--!1*/false/*/--!1*/;
Открывающий тег:
/*--!<идентификатор>*/
Закрывающий тег:
/*/--!<идентификатор>*/
Конкретных причин выбирать именно такой тег нет.
Обязательно должно выполняться только одно требование -- теги не должны влиять на компиляцию, т.е. по хорошему должны быть комметариями, которые сложно повторить случайно и непреднамеренно.
Идентификатор нужен для того, чтобы можно было адресно подставить необходимый текст или значение:
MutateAddBool(1, IsEnglish);
Эта строчка устанавливает значение для куска кода, облаченного в теги с идентификатором "1"
Mutate();
Здесь непосредственно происходит подмена кода в исходниках и компиляция нового исходного кода. Корректность подстановки кода и правильность синтаксиса полностью возложена на плечи того, кто этим будет пользоваться. Впрочем, для простых вещей это тривиальная задача.
И даже для уже не совсем простых вещей, как представленный выше скрипт, большой проблемы соблюдение корректности синтаксиса не вызывает.
Какие проблемы решаются:
1. запоминание последних (и не только) используемых настроек
2. адаптивность настроек.
-- возможность менять язык настроек и описания
-- возможность выводить дополнительные настройки в зависимости от значений базовых, в том числе показывать дополнительные настройки только при явном запросе их отображения.
Не забудьте, что для корректной работы необходимо разрешить импорт функций из DLL.
В аттаче архив с библиотекой mutate и разобранным выше скриптом.
В аттаче архив с библиотекой mutate и разобранным выше скриптом.
Спасибо тебе! Недавно нашел твой блог. До этого читал твои посты на mql4.com
ОтветитьУдалитьУспехов!