Еще одна задачка на правильное ООП

Тема в разделе "LANGS.C", создана пользователем Green_DiCk, 8 дек 2008.

  1. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    217.118.66.104

    Есть класс, объект которого может принимать неск-ко конечных состояний. Состояния должны меняться через заданный интервал времени. Как это лучше спроектировать?

    Т.к. есть такое понятие как "интервал времени", то надо периодически этот интервал времени проверять, т.е. нужен бесконечный цикл. Раз нужен цикл, то чтобы этим циклом не повесить объект надо бы этот цикл выделить в отдельный поток. Но для каждого экземпляра создавать отдельный поток, который бы менял состояния - по-моему жирно будет. т.е. поток хорошо бы один на все экземпляры. Проще всего конечно добавить в класс метод OnTick() и дергать его извне. Но это противоречит ООП. Объект должен сам себя переключать.

    Какие соображения?
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Вообщем это конечный автомат, класс который имеет конечное кол-во состояний.

    Так и делают, вызывают например метод Process этого самого конечного автомата. Внутри этого метода класс обрабатывает какие-то данные, и если это необходимо то он переключается в другое состояние. Если таких классов много, то для их обработки делают какой-нибудь менеджер, в который их помещают, и дёргают метод Process у самого менеджера.
     
  3. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Именно. Уточню то что сказал Booster - в base class надо определить интерфейс и во всех наследующих его реализовать:
    Код (Text):
    1. class IState
    2. {
    3. public:
    4.     virtual void Process(uint32 timestamp) = 0;
    5. };
    Обычно в таком коде есть ещё и другие события - приход данных и т.д. Схема именно такая.
     
  4. scf

    scf Member

    Публикаций:
    0
    Регистрация:
    12 сен 2005
    Сообщения:
    386
    Или так:
    Код (Text):
    1. Stateful *stateful = new Stateful();
    2. stateful->registerTimer(timer);
    3.  
    4. Stateful::Link<&StateFul::onTimer> timerLink;
    5. Stateful::registerTimer(timer) {
    6.   timerLink.init(timer);
    7. }
    timer выполняется или в отдельном потоке, или где-то у тебя в главном цикле.
    Правда, грамотная реализация этого дела нетривиальна, кури boost::signals
    К чему нужно стремиться:
    1. многопоточность
    2. автоматическая "разрегистрация" при уничтожении Stateful (можно добиться, используя объект "Связь", который знает о регистрации и уничтожает ее при вызове деструктора и разместив этот объект в качестве члена Stateful)

    И вообще очень рекомендую изучить концепцию синхронных, асинхронных и отложенных событий, например на основе CntmLib (документация прилагается). Правда, либа только под линукс, но идеи - они кроссплатформенные =)
     
  5. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    "...сам себя переключать..."

    Не похоже чтобы это противоречило ООП.
     
  6. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    217.118.66.104

    ок, камрады, я понял. сделаю как Booster c s0larian посоветовали. Тем более что менеджер у меня уже есть. Класс "Движок" содержит спрайты, которые должны менять свои картинки через опр. интервалы времени - анимация так сказать.

    scf, любопытный вариант, но для меня пока сложноват. Да и времени нет со всем этим заморачиваться. Я тут с stl еще не разобрался толком... так что может быть "в будующем"..

    Всем спасибо.