Russian Qt Forum

Программирование => Общий => Тема начата: Igors от Август 03, 2017, 11:56



Название: Расширение данных
Отправлено: Igors от Август 03, 2017, 11:56
Добрый день

Объект имеет обширный набор "параметров" организованных в виде дерева. Доступ к параметру осуществляется по уникальному ключу (ID), напр (псевдокод)
Код
C++ (Qt)
const int DIFFUSE_ID = 2070;
...
Param * param = object->GetParam(DIFFUSE_ID);
Сам нод дерева (param) нужен редко, зато очень часто его значение, напр
Код
C++ (Qt)
double value = object->GetParamValue(DIFFUSE_ID, currentTime);
Таких вызовов тысячи. Все работает, все хорошо. Но вот понадобилось дерево сделать динамическим, т.е. узлы могут добавляться и удаляться. С точки зрения дерева это выглядит так
Цитировать
...
  MATERIAL_ID     // Нод "материал" (все как сейчас)
    DIFFUSE_ID
    LUMA_ID
    ....
  MATERIAL_ID2     //  Еще один нод "материал" (теперь их может быть много)
    DIFFUSE_ID
    LUMA_ID
...
Как лучше всего адаптировать имеющийся (не маленький) код к этому изменению?

Спасибо


Название: Re: Расширение данных
Отправлено: qate от Август 03, 2017, 13:37
не совсем понятно что меняется при удалении и добавлении узла
ведь есть указатель на объект и по нему получить можно параметр
чтото еще изменилось ?


Название: Re: Расширение данных
Отправлено: Igors от Август 04, 2017, 09:44
не совсем понятно что меняется при удалении и добавлении узла
ведь есть указатель на объект и по нему получить можно параметр
чтото еще изменилось ?
Ткперь DIFFUSE_ID уже не является однозначным ключом. Напр Что должен делать объект чтобы получить значение не из первого а из второго узла "материал"?


Название: Re: Расширение данных
Отправлено: Bepec от Август 04, 2017, 19:25
Ну, или добавить ещё 1 параметр как "родителя", или сделать привязку к текущему узлу.

Как я вижу без изменения основных вызовов( добавляется только установка текущего параметра)
Код:
const int MATERIAL_ID = 2070;
...
// получаем DIFFUSE_ID из MATERIAL_ID
object->setCurrentParam(MATERIAL_ID);
double value1 = object->GetParamValue(DIFFUSE_ID, currentTime);

// получаем DIFFUSE_ID из MATERIAL_ID1
object->setCurrentParam(MATERIAL_ID1);
double value2 = object->GetParamValue(DIFFUSE_ID, currentTime);

Или же вариант с добавлением параметра
Код:
const int MATERIAL_ID = 2070;
...
// получаем DIFFUSE_ID из MATERIAL_ID
double value1 = object->GetParamValue(MATERIAL_ID, DIFFUSE_ID, currentTime);

// получаем DIFFUSE_ID из MATERIAL_ID1
double value2 = object->GetParamValue(MATERIAL_ID1, DIFFUSE_ID, currentTime);

Ну ещё можно зафигачить GetParamValue со значением по умолчанию для поддержки старого кода. Т.е. до первого найденного параметра DiffuseId

PS других вариантов, без масштабных изменений не вижу.


Название: Re: Расширение данных
Отправлено: Igors от Август 05, 2017, 10:57
Число параметров нода "материал" - где-то от 100 до 200 (точно не мерял). Число вызовов этих параметров - тысячи. При этом механизм GetParamValue используется повсеместно, не только для материала.

"Адаптация" вовсе не означает "менять как можно меньше", да, хотелрсь бы, но др соображения могут быть более важны. Напр здесь главное - обеспечить надежность вызовов, нужно сделать так чтобы старое GetParamValue выдавало ошибку компиляции при обращении к параметру материала (но продолжало работать для другого). Да, я получу тонны ошибок и буду править возможно неск дней - вот поэтому и надо очень тщательно продумать на что менять.
Код:
object->setCurrentParam(MATERIAL_ID);
double value1 = object->GetParamValue(DIFFUSE_ID, currentTime);
Нет той самой надежности

Код:
// получаем DIFFUSE_ID из MATERIAL_ID1
double value2 = object->GetParamValue(MATERIAL_ID1, DIFFUSE_ID, currentTime);
Не пресекается старый вызов. И кто ответит за MATERIAL_ID1? Это уже не константа

 


Название: Re: Расширение данных
Отправлено: Bepec от Август 06, 2017, 12:38
Если, как вы говорите, констант больше нет - надо всё переписывать.

Ну потому что кирпичей нет, а из треугольников домик не построишь.


Название: Re: Расширение данных
Отправлено: Igors от Август 07, 2017, 07:05
Если, как вы говорите, констант больше нет - надо всё переписывать.
Понятно что надо, вопрос каким образом. На что менять существующие вызовы?


Название: Re: Расширение данных
Отправлено: Igors от Август 07, 2017, 11:38
Я пока вижу такую схемку

1) Переименовать все константы нода "материал", напр X_DIFFUSE_ID вместо DIFFUSE_ID, это вызовет массовые ошибки компилятора, ну и хорошо

2) Править ошибки заменяя
Код
C++ (Qt)
double value = object->GetParamValue(DIFFUSE_ID, currentTime);
На
Код
C++ (Qt)
double value = object->GetMaterialValue(materialIndex, X_DIFFUSE_ID, currentTime);
Ну и по месту откуда-то брать тот materialIndex. В самом объекте мапы
Код
C++ (Qt)
double CObject::GetMaterialValue( uint materialIndex, uint  paramIndex, double currentTime )
{
 Q_ASSERT(materialIndex < m_MaterialMaps.size());
 int ID = m_MaterialMaps[materialIndex].value(paramIndex); // получаем реальное уникальное ID
 Q_ASSRERT(ID);
 return GetParamValue(id, currentTime);
}
При создании/удалении материалов парить m_MaterialMaps их владельцев. Критикуем, пинаем

Да, и неужели нет такого паттерна?  :)


Название: Re: Расширение данных
Отправлено: Bepec от Август 07, 2017, 13:14
Паттерны это дерево. Вы счас к нему всё и сводите.
А переделка с одного паттерна на другой к паттернам не относится :)

PS у вас нечего критиковать, вы привели мой второй вариант :)


Название: Re: Расширение данных
Отправлено: Igors от Август 07, 2017, 13:56
Паттерны это дерево.
Думал, может человек повзрослел (после длительного отсутствия). Какое там - все та же трещетка, абы чего написать, авось что-то да в масть. Идите отсюда, вертихвост эдакий  :'(


Название: Re: Расширение данных
Отправлено: Авварон от Август 07, 2017, 14:20
Думал, может человек повзрослел (после длительного отсутствия). Какое там - все та же трещетка, абы чего написать, авось что-то да в масть. Идите отсюда, вертихвост эдакий  :'(

О_о


Название: Re: Расширение данных
Отправлено: Racheengel от Август 07, 2017, 14:41
а если сделать ключи в виде "пути"?

objectPtr->GetParamValue("MATERIAL_ID2/DIFFUSE_ID");


Название: Re: Расширение данных
Отправлено: Bepec от Август 07, 2017, 19:08
Так это будут те же ключи :D
И проблему igors с тем, что ему переписывать всё придётся не исправят :D

to Igors я тебя тоже, !адекват, люблю :D


Название: Re: Расширение данных
Отправлено: Igors от Август 08, 2017, 10:28
а если сделать ключи в виде "пути"?

objectPtr->GetParamValue("MATERIAL_ID2/DIFFUSE_ID");
Проблема та же - где взять MATERIAL_ID2? (в смысле чему оно соответствует) Только здесь еще отягощенная строками.

Владелец - конечно объект. Юзер указывает что желает еще материал, может еще и еще (хотя и редко). Ну накидать их всех в дерево - дело несложной техники, имеющиеся структуры данных это позволяют. Но как их затем удобно использовать?


Название: Re: Расширение данных
Отправлено: Racheengel от Август 10, 2017, 10:57
Проблема та же - где взять MATERIAL_ID2? (в смысле чему оно соответствует)

А это называется "контрактом" между тем, кто спрашивает (он то знает, что ему надо) и тем, кого спрашивают. Обе стороны должны понимать, что это такое:

const QByteArray MATERIAL_ID2 = "Material2";

(например)


Название: Re: Расширение данных
Отправлено: Igors от Август 10, 2017, 11:45
А это называется "контрактом" между тем, кто спрашивает (он то знает, что ему надо) и тем, кого спрашивают. Обе стороны должны понимать, что это такое:
Так и предлагается обсудить условия этого "контракта".
const QByteArray MATERIAL_ID2 = "Material2";

(например)
Создаваемый юзером нод "материал" конечно имеет имя, но оно не уникально. Ну и по-прежнему "не въехали" - какое же const если их число переменное? 

Ладно, пожуем. Итак теперь "материалов" может быть не один а много. В любом случае владелец (объект) уже не может запросить просто "параметр материала", он должен указать (конкретизировать) какого именно. Каким образом? (предмет обсуждения). И второе: существующий сынтаксыс не пресекает старого обращения (теперь уже ошибочного). На больших объемах кода это актуально, тоже обсуждаем


Название: Re: Расширение данных
Отправлено: Racheengel от Август 10, 2017, 16:05
- Старый код придется переписать, т.к. он стал неоднозначным. Понимаю, что кода много, но иначе практически никак.
- Убрать все численные константы, т.к. все стало динамическим - в них больше нет смысла.
- Заменить их на строковые ID (QByteArray) - а тут уже полная свобода, материалы и параметры могут называться как душе угодно. Главное, чтобы соблюдался контракт между двумя сторонами (GetParameter("MaterialX/color") - должен быть распознан получателем как "цвет материала X, если такой имеется)


Название: Re: Расширение данных
Отправлено: Igors от Август 11, 2017, 07:11
- Старый код придется переписать, т.к. он стал неоднозначным. Понимаю, что кода много, но иначе практически никак.
Вопрос "переписывать или нет" вообще не стоит. Нужно чтобы переписанное хорошо "легло" и потом не пришлось месяцами ловить новые баги

- Убрать все численные константы, т.к. все стало динамическим - в них больше нет смысла.
- Заменить их на строковые ID (QByteArray)
"Все" не убрать, материал - лишь один из многих нодов дерева. И откуда упорное стремление к строкам? Здесь не вижу ни одной выгоды от них

а тут уже полная свобода, материалы и параметры могут называться как душе угодно. Главное, чтобы соблюдался контракт между двумя сторонами (GetParameter("MaterialX/color") - должен быть распознан получателем как "цвет материала X, если такой имеется)
Уже говорили что имена есть но не уникальны. И не раз говорили типа "откуда возьмется "MaterialX", т.е. кто и где будет хранить этот (в общем случае) ключ. Топчемся на месте


Название: Re: Расширение данных
Отправлено: Bepec от Август 11, 2017, 16:06
to Racheengel:
Это же Igors. Ему ответы уже всевозможные дали, но он будет зудеть до последнего, просто выводя из себя людей :D Темы поднимает неплохие, но вот окончательное решение у него одно - "всё уже есть, всё уже сказали, скажите чё-нить новое, чтоб решило проблему сразу".


Название: Re: Расширение данных
Отправлено: Racheengel от Август 11, 2017, 16:54
И откуда упорное стремление к строкам? Здесь не вижу ни одной выгоды от них

Однозначность ключей, убирается ограничение на численные константы. Лучше юзать строчку "MaterialX", чем const MATERIAL_X_ID = 12345; - это "12345" еще где-то надо определить, причем следить, чтоб никто больше нигде не переопределил его...

Цитировать
И не раз говорили типа "откуда возьмется "MaterialX", т.е. кто и где будет хранить этот (в общем случае) ключ. Топчемся на месте

Тут вообще не понял проблемы. "Хранить" значение будет тот, кто предоставляет материалы. А зачем хранить ключи?


Название: Re: Расширение данных
Отправлено: Igors от Август 12, 2017, 06:57
Тут вообще не понял проблемы. "Хранить" значение будет тот, кто предоставляет материалы. А зачем хранить ключи?
По указанию юзера создается новый нод "материал", он добавляется в дерево параметров объекта. Потом возможно еще нод "материал", и еще, а может и наоборот какой-то нод удалят. Сейчас объект просто обращается к ноду по константе, но c переменным числом таких нодов это уже не катит. Псевдокод
Код
C++ (Qt)
double value = GetParamValue(DIFFUSE_ID, currentTime);  // было
 
double value = GetMaterialValue(???, ???, currentTime);  // надо
 
Предложите реализацию GetMaterialValue. Разумеется объект знает к какому конкретно ноду "материал" он сейчас обращается, напр его индекс. Но нужна-то диффуза которая один из чайлд нодов данного материала,  закопана там глубоко


Название: Re: Расширение данных
Отправлено: Racheengel от Август 17, 2017, 13:00
Ну, если совсем грубо:

QMap<QByteArray, QVariant> MaterialParams;
QMap<QByteArray, MaterialParams> Materials;
Materials m_objectMaterials;

QVariant GetMaterialValue(QByteArray materialId, QByteArray paramId)
{
return objectMaterials[materialId][paramId];
}


Название: Re: Расширение данных
Отправлено: Igors от Август 17, 2017, 13:53
Ну, если совсем грубо:

QMap<QByteArray, QVariant> MaterialParams;
QMap<QByteArray, MaterialParams> Materials;
Materials m_objectMaterials;

QVariant GetMaterialValue(QByteArray materialId, QByteArray paramId)
{
return objectMaterials[materialId][paramId];
}
А чего Вы это замазываете суть (Q)вариантом? Создаваемые материалы должны помещаться в имеющееся дерево, этого никто не отменял.

[off]Эти подачи и возвраты по значению напоминают мне опустившегося человека - не бреется, ходит в рваных вонючих носках, бухает, жрет дуст...[/off]


Название: Re: Расширение данных
Отправлено: Авварон от Август 17, 2017, 16:28
[off]... не бреется, ходит в рваных вонючих носках, бухает, жрет boost...[/off]


Название: Re: Расширение данных
Отправлено: Bepec от Август 17, 2017, 16:57
каноничное завершение темы Igors :D


Название: Re: Расширение данных
Отправлено: kai666_73 от Август 17, 2017, 22:10
[off]Эти подачи и возвраты по значению напоминают мне опустившегося человека - не бреется, ходит в рваных вонючих носках, бухает, жрет дуст...[/off]
Типичный, конченный программер  :D


Название: Re: Расширение данных
Отправлено: Igors от Август 21, 2017, 10:56
Ладно, вернемся к единственному (пока) кандидату
Код
C++ (Qt)
double CObject::GetMaterialValue( uint materialIndex, uint  paramIndex, double currentTime )
{
 Q_ASSERT(materialIndex < m_MaterialMaps.size());
 int ID = m_MaterialMaps[materialIndex].value(paramIndex); // получаем реальное уникальное ID
 Q_ASSRERT(ID);
 return GetParamValue(id, currentTime);
}
При создании/удалении материалов парить m_MaterialMaps их владельцев. Критикуем, пинаем
Ничего "плохого" здесь не вижу, да и реализовать это реально. Но вот с "идейной" точки зрения мне как-то не нравится. Ведь только что объект был "совершенно свободен", все делалось механизмом дерева параметров. Добавлять новые параметры и удалять старые - не вопрос, и это не требует никаких изменений в данных. Нужен параметр для расчетов/использования - дернул его по ключу - и все. А теперь мы начинаем хранить ID ключей - ну как минимум надо обеспечивать их (де)сериализацию, т.е. появились данные (члены класса объект). Хмм...


Название: Re: Расширение данных
Отправлено: Bepec от Август 21, 2017, 14:22
А вы в любой своей реализации храните свои ключи параметров.
Просто в первом случае они были константами, теперь стали переменными.

PS нашли корову в коровьем стаде, красота :)