Re[23]: Rsdn.Editor
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.01.06 01:26
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Кстати, а почему для рисования TextRenderer не используется? Или он совсем недавно появился.


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

ВВ>ОК, я понял. "Мне кажется странным, что работа со строками ведется в лоб, а не используется какой-либо из алгоритмов, позволяющих эффективно модифицировать строки". Так лучше?


Э какой хитрый. Ты мне статистику хотя бы приведи. Мол воодил текст минуту... исчерпалась вся память в системе. Или еще что. А так "кажется". Мне вообще страшно смореть как целые объекты — команды на каждое нажатие кнопки создаются и уничтожаются пачками. Но я же креплюсь?!

ВВ>Я немножко не об этом. Бог с ней, с памятью. Непонятно почему данные хранятся как, фактически, массив строк. Это было наиболее удобным/эффективным решением?


По-моему — да. Кстати, в Сцинтиле сделано (вроде бы) точно так же.

ВВ> Потому что на настоящий момент по крайней мере одна проблема имеет место быть — то вся работа со стилями как бы "привинчена" к конкретной строке, что несколько неудобно.


Дык, это принципиальное дизайнерское решение. Именно это позволяет редактировать 15-ти мегабайтный файл и усом не вести.

Ведь сдвижка байтов в огромном файле это не единственная проблема. (Хотя и актуальная. Создай, например, 15 метровый файл и попробуй оредактировать его с конца в Нотпэде) Главная проблема — это подсветка! Если ее делать для всего файла, то каюк. Уже на 300 килобайтном файле начинаются тормоза. А метровый становится вообще не подъемным. Надо вводить какой-то квант. Строка, точнее параграф (строки могут переноситься) как раз и является оптимальным выбором. Сюдаже прекрасно вписывается и то, что отрисовка идет по строкам. Да и прокрутка.

Как еще, по-твоему, организовать работу в реальном времени с большими файлами?

ВВ>Ну ты же не жалуешься на то, что List<String> жрет слишком много памяти по сравнению со string[].


Не жалуюсь, так как это копейки. Он хранит ссылки. И его оверхэд в худщем случае 2х. По сравнению с объемом памяти затрачиваемым на строки — это фигня. Зато он дает молниеносное изменение размера массива.

ВВ> А здесь аналогия примерно такая же — да, мы оставляем дыры, тратим лишние байты, но благодаря этому можем делать in-place модицирование строки. Впрочем, достаточно об этом.


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

ВВ>Кстати, неплохой идеей было бы как-то выделить низкоуровевый код отвечающий за работу с текстом — как это сделано в шарп-девелопе например. Чтобы при желании, если например потребуется сделать на основе Rsdn.Editor редактор для сверх-больших файлов можно было бы легко и просто это участок поменять.


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

ВВ>А чем отличается "низкоуровневая абстракция" char* от System.String? Наличием звездочки?


Хотя бы тем, что она безопасна и содержит информацию о длинне. Мне не нужно таскать за собой еще int с ее размером и везде расставлять провекри не вышел ли я за пределы. Но я то говорил не о string. Я то говорил о такой абстракции как строка документа или строка представления. Я, в отличии от разработчиков Сцинтилы, чаще манипулирую объектами, а не низкоуровневыми абстракциями.

ВВ>Дык или я чего-то не понял или текст у тебя все-таки хранится не в виде простой строки, а виде _массива_ строк.


Массива, массива. И не строк в смысле string, а строк в смысле DocumentRow. И по-моеуму — это правильно.

ВВ>А как будет в дальнейшем расширяться функциональность? Т.е. ты описал через эти интерфейсы примитивные операции, но помимо них будут и другие — да и собственно уже есть.


Вообще-то для текстового редактор команд редактирования достаточно. И развивать их реально вряд ли потребуется. Но если что... классы я не запечатывал. Так что создаешь наследника и вперед... с песней.

ВВ>Почему нет, например, SetStyleCommand?


Потму что это не операция редактирования. Стили зависят от текста. Так что их бессмысленно назначать в произвольное время. Их нужно обновлять для обновленного участка текста. Квантом обновления является строка. Так что вместо SetStyleCommand есть интерфейс IFormatter, а в нем методы:
void StartParse(DocumentRowCollection rows, int startState);
void PrepareRows(DocumentRowCollection rows);
int PrepareRows(DocumentRowCollection rows, int start, int count);

На сегодня ты должен реализовать их и в них уже разначить нужные стили, для заданных строк. В будущем выделим стайлер в отдельный класс и вообще сделаем генерируемым. Ну, а для ручной "подстройки" сделаем события.

ВВ>Я не против идеи, идея интересная, но зачем 1) выставлять наружу детали реализации (всякие InsertCommand, DeleteCommand и пр.);


Начем с того, что их не обязательно использовать. Более того их вовсе не нужно использовать если ты не решил залудить что-то уж особо ядреное. Я тебе привед список методов которых вполне достаточно для того втобы как угодно надругаться над документом. Кстати, код контроллера и представления вообще не обращается к методам работающим с ICommand.
А закончим тем, что ICommand и все кто его реализуют вполне законченные классы и их без проблем можно использовать для расширения рботы редактора. Например, их можно использовать для записи и воспроизведения макросов. Они леко сереализуются... в общем это внутренняя механика досупная во вне, но не обязательная для использования. Ты же не докапывашся до тех кто делал Ворд, что они выставляют его объектную модель в скрипты?

ВВ> это должны ИМХО быть частные реализации, иначе представь как загрузится АПИ если "дописать" сюда команд,


Хм. В интерфейсе документа есть ровно один метод для явной работы с командами это:
void ExecuteCommand(ICommand command);

Конечно можно и его скрыть, но имеет ли это смысл? Не уж то от этого интерфейс так упростится? А сами классы команд можно просто не описывать.

ВВ> 2) такой подход должен быть наверное общим, а не избирательным, а то придется смотреть что реализовано в качестве команды, а что в качестве DocumentRow.XXX.


Не понял. А что не общего в подходе? Это паттерн. Паттерн примененный по его прямому назначению. Неужели это не очевидно?

VD>>Возможно отчасти потому, что Сцинтиле много лет и всей все уже отработно, а у меня работа со стилями откровенно не доделана.


ВВ>Вот, было подозрение И наверное лучше сначала доделать.


Точно лучше. Но вот мы, видишь, заняты... беседуем.

VD>>При этом исчезает еще одна проблема. Ты не ограничен количеством битов отводимых на стиль. Размер массива может быть любым! А вот в Сцинтиле, если мне не изменяет память, количество стилей не дожно привышать 16.


ВВ>Да ладно уж, там почти целый байт.


Почти! Байт — это 8 бит. То есть еще меньше.

ВВ> Кстати int32 мне тоже кажется небольшим излишеством — хотелось бы например иметь возможность ассоциировать какую-нибудь custom-информацию со строкой (например, для browser-like навигации по тексту), не отводить же для этого очередной Int?


Я сначала сделал тип состояния обобщенным (задаваемым параметром у класса), но быстро отказался от этой идеи, так как стайлеры могут быть разные и они могут меняться для одного и того же документа в реальном времени. Опять же в качестве примера приведу формат сообщения януса. В нем могут быть волженные участки на разных языках. Каждый из них хранит свой набор стилей и свои состояния.

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

ВВ>А как ты себе представляешь генератор лексеров?


Легко. На входе лексическая грамматика описывающая правила и некая таблица соотвествия между правилами и стилями редактора. На выходе код класса который парсит строки и выдает заполненный массив AppliedStyle-ей.

ВВ> Т.е. чего он будет генерировать и на основе чего?


Как и сейчас на основе грамматики заданной в виде декста. Ну, плюс описание стилей и ассоциация стилей с правилами.

ВВ> У меня кстати была в свое время сделать что-то типа враппера над кокой — т.е. на основе простой описанной в ХМЛ грамматике генерится EBNF-грамматика для коки, на основе которой уже динамически собирается парсер. Однако особых бенефитов такой способ не даст, а гемора будет не много.


А зачем здесь ХМЛ? Описание грамматики вообще не задача. Если бы дело было только в ней, то я бы давно ее действительно на ХМЛ-е сбацал. Сложность в создании эффективного ДКА лексера по этой грамматике. Коко это делает очень неплохо. Тлько она генерирует не то. Она генериует класс Scanner который конечно удобен для скармливания его парсерам, но для стайлера это перебор. К тмоу же у него есть еще один недостаток. В том виде в котором он существует сейча он не пригоден для использования в стайлере. Ведь генерируемый им код хранит состояние хотя и в виде целого числа, но не там. Это число хранится в виде локальной переменной, а надо, чтобы егом ожно было задавать и считывать извне. К тому же он не чесно обрабатывает комментарии. Он их просто пропускает (впесте с вложенными концами строк), а надо их чесно парсить как часть грамматики. Это позволит останавливать парсинг в конце строки даже если она находится внтри многострочного комментария или строки.

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


Хм. Для каждой грамматики лексер будет свой. Или он будет не очень эффективным. Можно конечно попробовать создать некий вариант который позволяет менять тип строк, список ключевых строк, коментариев и т.п. Но это будет не самое эффективное решение и уж точно не самое гибкое. Уж если делать, то делать так чтобы было приятно посмотреть.
... << RSDN@Home 1.2.0 alpha rev. 631>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.