LINUX.ORG.RU

Объявление коллбека для граф. функций

 ,


0

1

Добрый день!

Есть некий проект X, для него есть подпроект Y. Y - подключаемая библиотека, которая парсит файл инструкций и дергает функции графики для выполнения инструкций. Появилось желание сделать Y независимым проектом (ибо в нем достаточно мощный механизм парсинга). Сейчас объявление коллбеков в Y выглядит примерно так:

XErrorCode XGraphPixelSet(int index, uint32_t color, int x, int y);
XErrorCode XGraphDrawLine(int index, int x1, int y1, int x2, int y2, uint32_t color, XGraphLineStyle aa);
XErrorCode XGraphDrawLineGrad(int index, int x1, int y1, int x2, int y2, uint32_t color1, uint32_t color2, XGraphLineStyle aa);
// и т.п.
Т.е. в текущем варианте эти функции сильно завязаны на реализацию в проекте X (код ошибки, стиль линии (AA или не AA), передача index'а изображения для операций над ним, и т.п.).

Есть мысль согласно UNIX-идеологии вообще убрать работу с графическими функциями из Y - и сделать в нем вообще только несколько функций наружу - Init, LoadFile, AddElementIdWeNeedToParseInFileIHateLongFunctionsNames, GetParsedStruct, а последней функцией возвращать в X (или в другой проект, если Y стал независимым) заполненную структуру, значения которой Y распарсил из файла, сами typedef'ы структуры объявить в libY.h.

Что скажете?

★★

А почему бы не юзать:

typedef struct {
  int32_t x, y;
} point_t;

Сейчас объявление коллбеков в Y выглядит примерно так:

У тебя тогда X подпроект Y, ибо ты получается дёргаешь напрямую функции из него - это получаются не калбеки, а прямой вызов. Теперь ты реально хочешь сделать Y подпроектом.

Есть мысль согласно UNIX-идеологии вообще убрать работу с графическими функциями из Y - и сделать в нем вообще только несколько функций наружу - Init, LoadFile, AddElementIdWeNeedToParseInFileIHateLongFunctionsNames, GetParsedStruct, а последней функцией возвращать в X (или в другой проект, если Y стал независимым) заполненную структуру, значения которой Y распарсил из файла, сами typedef'ы структуры объявить в libY.h.

Т.е. взять буфер и захреначить в него 100500 callid+args? А потом передать его в X и исполнить - да, можешь и так. Если парсить твои файлы в какой-то промежуточный формат, потом о5 парсить и исполнять - это не юниксвей, особенно есть это тебе не нужно.

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

Если же ты функции из X передаёшь в Y через какую-то жопу и там реально какие-то калбеки, то второй вариант по мне лучше вытащить функции работы с графикой в «подпроект» и дёргать их напрямую без взяской мароки из Y.

anonymous
()
Ответ на: комментарий от anonymous

Если же ты функции из X передаёшь в Y через какую-то жопу и там реально какие-то калбеки, то второй вариант по мне лучше вытащить функции работы с графикой в «подпроект» и дёргать их напрямую без взяской мароки из Y.

Если же ты функции из X передаёшь в Y через какую-то жопу и там реально какие-то калбеки, то второй вариант лучше, но по мне ещё лучше вообще вытащить функции работы с графикой в «подпроект» и дёргать их напрямую безо взяской мароки из Y.

anonymous
()
Ответ на: комментарий от anonymous

зачем это надо, если распарсить+выполнить проще, чем морока с буферами.

Подпроект Y парсит CSS файл, и в текущем виде прототипа делает это довольно-таки неплохо. Просто я подумал, что возможно парсер CSS под LGPL может кому-нибудь после пригодиться.

Т.е. взять буфер и захреначить в него 100500 callid+args?

Почти. Примерно так:

YCSSElements * outresult;

YInit();
YAddElem("div", "myclass", "");
YAddElem("p", "myp", "mypid");
int myp = YAddElem("p", "myp", "secondid");
YAddElem("form", "inputformclass", "");
YLoadFile("./default.css");
YLoadFile("./userstyle.css);
YGetResult(outresult);

outresult.elements[myp].properties[BORDER_WIDTH].value, blah blah blah...
sambist ★★
() автор топика

в текущем варианте эти функции сильно завязаны на реализацию в проекте X

Это вроде очевидно, надо переделать так, что бы парсер оперировал исключительно понятиями разбираемого файла и в коде никак бы ни фигурировало то, что надо делать с разобранными элементами. Коллбеки могут иметь вид:

foundSomeItem1()
foundSomeItem2()
foundSomeItem3()

а последней функцией возвращать в X (или в другой проект, если Y стал независимым) заполненную структуру, значения которой Y распарсил из файла

Тут таже самая ситуация, что с парсерами XML. Тебе надо определиться, что тебе надо: SAX или DOM.

pathfinder ★★★★
()
Последнее исправление: pathfinder (всего исправлений: 1)
Ответ на: комментарий от pathfinder

Тебе надо определиться, что тебе надо: SAX или DOM.

Имеете в виду механизм коллбеков SAX'a? Как-то не хочется такого.

Вот тут я показал, чего приблизительно хочу добиться. Т.е. если не было вызова AddElem для какого-то элемента, то и не вносить его параметры в «базу» (outresult). В конце по сути возвращается DOM-структура, только без связей родитель-потомок (связи уже будет тот, кто вызвал либу крутить, цезарю-цезарево, парсеру-парсерово, можно, в принципе, прикрутить поле для «parent», в теории тогда да, можно будет более полноценно CSS разбирать).

sambist ★★
() автор топика
Ответ на: комментарий от sambist

Имеете в виду механизм коллбеков SAX'a? Как-то не хочется такого.

Значит, тебе коллбеки не нужны вообще. Делай некое подобие DOM-парсера который выделяет в оперативной памяти место под разбираемую структуру. SAX-подобный парсер с коллбеками нужен лишь тогда, когда надо разбирать файлы огромного размера так, чтобы он быстро работал и потреблял при этом небольшое количество памяти.

Добавлять или не добавлять к парсеру опции для включения/не включения определенных элементов в выходную структуру, это твое дело.

Единственное, что надо помнить, что выходная структура DOM-парсера и рабочая структура, которая в итоге будет содержать распарсенную информацию, это не одно и тоже. Первая должна оперировать понятиями формата, вторая должна оперировать понятиями, заложенными в прикладную логику программы. Видно, что будет оверхед на преобразовании «структура парсера -> рабочая структура». Но в большинстве случаев удобство работы с DOM-подобным парсером важнее его недостатков .

pathfinder ★★★★
()
Последнее исправление: pathfinder (всего исправлений: 3)
Ответ на: комментарий от pathfinder

А почему, кстати, нельзя избавиться от перехода? Что такого будет содержать парсер, чего не будет рабочая и наоборот.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

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

Можно, конечно, сделать код парсера исключительно под данную программу, а не под что-либо ещё. Парсер будет неразрывно логически связан с логикой основной программы. Тогда можно генерировать на выходе строго рабочую структуру. Но тогда я не понимаю, зачем оформлять парсер в виде отдельной библиотеки.

Трудно говорить обобщенными словами. Понятно, что каждый случай уникален и могут быть свои особенности. Если тебе нужна малая связанность кода парсера и кода самой программы (хейтеры спагетти-кода высоко ценят малую связанность), то преобразование «структура парсера -> рабочая структура» неизбежно.

pathfinder ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.