Russian Qt Forum

Программирование => Общий => Тема начата: Igors от Декабрь 01, 2021, 10:24



Название: Взаимодействие классов линейки времени
Отправлено: Igors от Декабрь 01, 2021, 10:24
Добрый день

Предельно упрощенно - классы "линейки времени"

Само/собсно время + значение
Код
C++ (Qt)
struct KeyFrame {
..
 double m_time;
 double m_value;
..
};

KeyFrames хранятся в контейнере
Код
C++ (Qt)
struct KeyList {
..
Container<KeyFrame> m_keys;
..
};

И предъявляются в UI в виде "анимационного канала"
Код
C++ (Qt)
struct KeyChannel {
QString m_name;
int m_uniqueID;
..
QScopedPointer<KeyList> m_list;
..
};

И вот возникает задачка - когда юзер меняет время m_time одного (или нескольких) KeyFrame(s) (для заданного/специфичного канала)- нужно автоматычно пересчитать значение(я) в др канале. Варианты:

1) "Полный ручняк" - найти все места где меняется m_time и присобачить к ним if'ы. Однако мест таких ожидается по меньшей мере десятки. Да и латки if'ами не выглядят хорошо

2) "Полный автомат" - делать изменения в сеттере KeyFrame::SetTime. Но KeyFrame не знает кому он принадлежит, впрочем  KeyList тоже. Также "target" (кого надо менять) может отсутствовать (напр на загрузке)

3) "Месяги/Сигналы" - то же что в "2". Послать.. а кому? И что?

Что посоветуете?

Спасибо


Название: Re: Взаимодействие классов линейки времени
Отправлено: Igors от Декабрь 06, 2021, 08:24
Не вижу энтузиазма :) Оно и понятно, вот "почитать", а еще лучше "собирать" - то да, а тут такая бяка... Ну ладно, покатаем очевидное

Вот класс самого верхнего уровня KeyChannel. Для него послать сигнал - без проблем, т.к. он имеет уникальный id, его видят в UI и.т.п. Попробуем так
Код
C++ (Qt)
void KeyChannel::SetNthKeyTime( int keyIndex, double time );
Но менять KeyFrame::m_time только так я не могу - есть еще KeyList что меняет m_time когда захочет. А нужен ли KeyList? Да, KeyChannel может иметь нулевой KeyList (типа нод дерева, контейнер др KeyChannel(s)). KeyList может свапаться и существовать сам по себе. Да и вообще, пусть KeyList занимается KeyFrame(s) - эл-тами своего контейнера, а всякие там m_name, m_id - это уже др уровень. (мухи отдельно и все такое)

Ладно, еще вариант
Код
C++ (Qt)
struct KeyFrame {
..
 double m_time;
 double m_value;
 KeyList * m_owner;
..
};
И аналогично для KeyList. Так получаю массу забот напр на операциях copy/paste - все время надо присматривать за m_owner что может оказаться хлопотно и ненадежно.

Что интересно - возникшая задача (реагировать на изменения времени ключа) - довольно скромная фича, неужели для нее надо менять так принципиально?
Цитировать
Это потому что корявая архитектура! Вот если бы изначально все было продумано.. и.т.п.
Ну так хорошо, предлагаем "некорявую". И тут ответ(отмазка) известен
Цитировать
Ну так надо же знать задааачу..
Что на деле означает "будет жрать std и ни хрена не делать"  :'(


Название: Re: Взаимодействие классов линейки времени
Отправлено: Old от Декабрь 06, 2021, 08:54
Заходишь в темы к Igors, а там ничего не меняется, одни страданья: "никто не помогает, не обсуждает, а у меня ничего не получается". :)
И сводятся эти страдания к "ну это потому, что вы тут все ничего не знаете, не делаете и вообще разобрались с шаблонами и std, да еще и пользуетесь всем этим". :)

Но не буду отвлекать, продолжайте страдать, это у вас получается лучше всего. :)


Название: Re: Взаимодействие классов линейки времени
Отправлено: DarkHobbit от Декабрь 09, 2021, 14:40
О, баттл!  ;D

Но на самом деле ТС сам себе правильно ответил, что

Цитировать
Ну так надо же знать задааачу..
  ;D

Я вот не уверен, что из объяснений я правильно понял задачу. Но если вкратце - я бы прикрутил ко всему этому сбоку некий ChannelsAndFramesManager, который и следит за целостностью всего описанного выше безобразия. И все запросы на изменения - строго через него.

Сигналы/сообщения могут помочь в его организации, но не вместо него.

Это не единственный подход. Но я бы сделал так.


Название: Re: Взаимодействие классов линейки времени
Отправлено: Igors от Декабрь 10, 2021, 09:09
Я вот не уверен, что из объяснений я правильно понял задачу.
Ну позиция "непонимающего" довольно удобна  :)

Но если вкратце - я бы прикрутил ко всему этому сбоку некий ChannelsAndFramesManager, который и следит за целостностью всего описанного выше безобразия. И все запросы на изменения - строго через него.
Пример
Код
C++ (Qt)
void KeyList::CalcVelocity( ...)
{
 ..
 SetKeyTime(keyIndex, time);
 ...
}
Какие претензии к KeyList ? Он владеет всеми ключами (KeyFrames), знает что делать (CalcVelocity) - ну он время ключей считает и ставит, не вижу тут никакой  (архитектурной) ошибки. Проблема в том что KeyList никак не может связаться с др KeyList'ами что принадлежат др KeyChannel'ам.

ChannelsAndFramesManager - ну класс сбоку (припеку) никогда не выглядит хорошо  :) Он ничем не владеет, ничего не имеет - как он может что-то решать? Ну допустим заменим SetKeyTime на ChannelsAndFramesManager::SetTime, що це дало? Связки как не было так и нет


Название: Re: Взаимодействие классов линейки времени
Отправлено: qtkoder777 от Декабрь 10, 2021, 19:12
KeyFrame храним в двусвязном списке. Каждый KeyFrame знает своего соседа и может ему выставить то что надо (m_time разумеется меняем только методом).


Название: Re: Взаимодействие классов линейки времени
Отправлено: Igors от Декабрь 11, 2021, 13:45
KeyFrame знает своего соседа
А так и есть  :) (оставлено для совместимости со старым кодом). Только что толку от знания соседей - они такие же KeyFrame(s). Менять надо данные (KeyFrame) принадлежащие др KeyList которым владеет др KeyChannel

Видимо очередной пост "для оживления форума"  :)