so_4: Версия 4.2.7. Слияние содержимого состояний

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

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

Для преодоления этих проблем в версии 4.2.7 добавлена возможность слияния (merge) содержимого двух состояний. Для использования слияния в описании состояния агента нужно указать макрос SOL4_STATE_MERGE(), в котором указать:

Например, пусть есть базовый класс a_base_t, в котором описывается состояние st_normal. И есть производный от a_base_t класс a_derived_t, в котором требуется переопределить состояние st_normal. Осуществляется это следующим описанием:

SOL4_CLASS_START( a_derived_t )

  SOL4_SUPER_CLASS( a_base_t )

  SOL4_STATE_START( st_normal )
    SOL4_STATE_MERGE( a_base_t, st_normal )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

При использовании макроса SOL4_STATE_MERGE() все события из указанного состояния включаются в состояние-приемник. При этом допускается, чтобы в состоянии-источнике были указаны имена событий, которые перечислены и в состоянии-приемнике:

SOL4_CLASS_START( a_base_t )

  ...

  SOL4_STATE_START( st_normal )
    SOL4_STATE_EVENT( evt_a )
    SOL4_STATE_EVENT( evt_b )
    SOL4_STATE_EVENT( evt_c )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()
SOL4_CLASS_START( a_derived_t )

  SOL4_SUPER_CLASS( a_base_t )

  SOL4_STATE_START( st_normal )
    SOL4_STATE_MERGE( a_base_t, st_normal )

    SOL4_STATE_EVENT( evt_b )
    SOL4_STATE_EVENT( evt_c )
    SOL4_STATE_EVENT( evt_d )

  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

Макрос SOL4_STATE_MERGE() может указываться в описании состояния более одного раза. Это может оказаться полезным, например, при использовании множественного наследования.

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

Если же в результате слияния в состоянии оказываются нежелательные события (например, которые были актуальны для этого состояния в базовом классе, но должны быть запрещены для этого состояния в производном классе), мо изъять состояние из списка разрешенных можно посредством макроса SOL4_STATE_EXCLUDE_EVENT(). Например, в следующем примере:

SOL4_CLASS_START( a_base_t )

  ...

  SOL4_STATE_START( st_normal )
    SOL4_STATE_EVENT( evt_a )
    SOL4_STATE_EVENT( evt_b )
    SOL4_STATE_EVENT( evt_c )
    SOL4_STATE_EVENT( evt_d )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()
SOL4_CLASS_START( a_derived_t )

  SOL4_SUPER_CLASS( a_base_t )

  SOL4_STATE_START( st_normal )
    SOL4_STATE_MERGE( a_base_t, st_normal )

    SOL4_STATE_EVENT( evt_d )
    SOL4_STATE_EVENT( evt_e )
    SOL4_STATE_EVENT( evt_f )

    SOL4_STATE_EXCLUDE_EVENT( evt_a )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()
в состоянии st_normal в классе a_derived_t будут разрешены к обработке события:

Макрос SOL4_STATE_EXCLUDE_EVENT() может указываться в описании состояния более одного раза.


Документация по SObjectizer v.4.4 'Тебуломста'. Последние изменения: Thu Sep 18 10:26:48 2008. Создано системой  doxygen1.5.6 Intervale SourceForge.net Logo