äžè¬ã«ãã¢ã¯ã¿ãŒã䜿çšãããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®äœæã¯ç°¡åã§æ¥œãããã®ã§ãã 俳åªèªèº«ãç°¡åãã€èªç¶ã«æžãããŠããããã§ãã ã¢ã¯ã¿ãŒã³ãŒãã®èšè¿°ãä»äºã®æãç°¡åãªéšåã§ãããšèšãããšããã§ããŸãã ãããã俳åªãæžããããšããéåžžã«è¯ã質åãçããŸãïŒããã®äœåã®æ£ç¢ºãããã§ãã¯ããæ¹æ³ã¯ïŒã
質åã¯æ¬åœã«ãšãŠãè¯ãã§ãã äžè¬çã«ä¿³åªã«ã€ããŠãç¹ã«SObjectizerã«ã€ããŠè©±ããšããç§ãã¡ã¯å®æçã«åœŒã«å°ããããŸãã ãããŠæè¿ãŸã§ããã®è³ªåã«ã¯äžè¬çãªçšèªã§ããçããããŸããã§ããã
ãããã ããŒãžã§ã³5.5.24ããªãªãŒã¹ãã ãã¢ã¯ã¿ãŒã®ãŠããããã¹ãã®å®éšçãµããŒããç»å ŽããŸããã ãããŠããã®èšäºã§ã¯ããããäœã§ããããã©ã®ããã«äœ¿çšããããã©ã®ããã«å®è£ ãããŠãããã«ã€ããŠã話ããŸãã
ã¢ã¯ã¿ãŒãã¹ãã¯ã©ã®ããã«èŠããŸããïŒ
SObjectizerã®æ°æ©èœã«ã€ããŠãããã€ãã®äŸã§æ€èšããäœãäœã§ããããäŒããŸãã è°è«ãããäŸã®ãœãŒã¹ã³ãŒãã¯ã ãã®ãªããžããªã«ãããŸã ã
ã¹ããŒãªãŒå šäœãéããŠãã俳åªããšããšãŒãžã§ã³ãããšããçšèªã¯åãæå³ã§äœ¿çšãããŸãã ãããã¯åããã®ãæå®ããŸãããSObjectizerã§ã¯ããšãŒãžã§ã³ãããšããçšèªãæŽå²çã«äœ¿çšãããŠãããããããã«ããšãŒãžã§ã³ãããããé »ç¹ã«äœ¿çšãããŸãã
PingerãšPongerã䜿çšããæãç°¡åãªäŸ
ã¢ã¯ã¿ãŒPingerãšPongerã®äŸã¯ãããããã¢ã¯ã¿ãŒãã¬ãŒã ã¯ãŒã¯ã®æãäžè¬çãªäŸã§ãã å€å žãšãèšããŸãã ããã§ããããããªããå€å žããå§ããŸãããã
ãã®ãããäœæ¥ã®éå§æã«PongerãšãŒãžã§ã³ãã«Pingã¡ãã»ãŒãžãéä¿¡ããPingerãšãŒãžã§ã³ããããŸãã PongerãšãŒãžã§ã³ãã¯Pongã¡ãã»ãŒãžãéãè¿ããŸãã C ++ã³ãŒãã§ã¯æ¬¡ã®ããã«ãªããŸãã
// Types of signals to be used. struct ping final : so_5::signal_t {}; struct pong final : so_5::signal_t {}; // Pinger agent. class pinger_t final : public so_5::agent_t { so_5::mbox_t m_target; public : pinger_t( context_t ctx ) : so_5::agent_t{ std::move(ctx) } { so_subscribe_self().event( [this](mhood_t<pong>) { so_deregister_agent_coop_normally(); } ); } void set_target( const so_5::mbox_t & to ) { m_target = to; } void so_evt_start() override { so_5::send< ping >( m_target ); } }; // Ponger agent. class ponger_t final : public so_5::agent_t { so_5::mbox_t m_target; public : ponger_t( context_t ctx ) : so_5::agent_t{ std::move(ctx) } { so_subscribe_self().event( [this](mhood_t<ping>) { so_5::send< pong >( m_target ); } ); } void set_target( const so_5::mbox_t & to ) { m_target = to; } };
ç§ãã¡ã®ã¿ã¹ã¯ã¯ããããã®ãšãŒãžã§ã³ããSObjectizerã«ç»é²ãããšãPongerãPingã¡ãã»ãŒãžãåä¿¡ããPingerãå¿çãšããŠPongã¡ãã»ãŒãžãåä¿¡ããããšãæ€èšŒãããã¹ããäœæããããšã§ãã
OK docteståäœãã¹ããã¬ãŒã ã¯ãŒã¯ã䜿çšããŠãã®ãããªãã¹ããèšè¿°ãã 次ã®ãã®ãååŸããŸãã
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include <doctest/doctest.h> #include <ping_pong/agents.hpp> #include <so_5/experimental/testing.hpp> namespace tests = so_5::experimental::testing; TEST_CASE( "ping_pong" ) { tests::testing_env_t sobj; pinger_t * pinger{}; ponger_t * ponger{}; sobj.environment().introduce_coop([&](so_5::coop_t & coop) { pinger = coop.make_agent< pinger_t >(); ponger = coop.make_agent< ponger_t >(); pinger->set_target( ponger->so_direct_mbox() ); ponger->set_target( pinger->so_direct_mbox() ); }); sobj.scenario().define_step("ping") .when(*ponger & tests::reacts_to<ping>()); sobj.scenario().define_step("pong") .when(*pinger & tests::reacts_to<pong>()); sobj.scenario().run_for(std::chrono::milliseconds(100)); REQUIRE(tests::completed() == sobj.scenario().result()); }
ç°¡åããã§ãã ããã§äœãèµ·ãããèŠãŠã¿ãŸãããã
ãŸãããšãŒãžã§ã³ããã¹ããµããŒãããŒã«ã®èª¬æãã¢ããããŒãããŸãã
#include <so_5/experimental/testing.hpp>
ãããã®ããŒã«ã¯ãã¹ãŠãso_5 :: Experimental :: testingåå空éã§èª¬æãããŠããŸããããã®ãããªé·ãååãç¹°ãè¿ããªãããã«ãçããŠäŸ¿å©ãªãšã€ãªã¢ã¹ãå°å ¥ããŸãã
namespace tests = so_5::experimental::testing;
以äžã¯ãåäžã®ãã¹ãã±ãŒã¹ã®èª¬æã§ãïŒããã§ã¯ãã以äžå¿ èŠãããŸããïŒã
ãã¹ãã±ãŒã¹å ã«ã¯ãããã€ãã®éèŠãªãã€ã³ãããããŸãã
ãŸããããã¯SObjectizerã®ç¹å¥ãªãã¹ãç°å¢ã®äœæãšèµ·åã§ãã
tests::testing_env_t sobj;
ãã®ç°å¢ããªããšããšãŒãžã§ã³ãã®ããã¹ãå®è¡ãã¯å®äºã§ããŸããããããã«ã€ããŠã¯å°ãåŸã§èª¬æããŸãã
testing_env_tã¯ã©ã¹ã¯ãSObjectizerã®wrapped_env_tã¯ã©ã¹ã«éåžžã«äŒŒãŠããŸãã åæ§ã«ãSObjectizerã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã§éå§ãããã¹ãã©ã¯ã¿ãŒã§åæ¢ããŸãã ãã®ããããã¹ããèšè¿°ãããšãã«ãSObjectizerã®éå§ãšåæ¢ã«ã€ããŠèããå¿ èŠã¯ãããŸããã
次ã«ãPingerããã³PongerãšãŒãžã§ã³ããäœæããŠç»é²ããå¿ èŠããããŸãã ãã®å ŽåããããããšãŒãžã§ã³ãã®æ±ºå®ã«ãããã®ãšãŒãžã§ã³ãã䜿çšããå¿ èŠããããŸãã ããã¹ãã·ããªãªãã ãããã£ãŠããšãŒãžã§ã³ããžã®ãã€ã³ã¿ãŒãåå¥ã«ä¿åããŸãã
pinger_t * pinger{}; ponger_t * ponger{}; sobj.environment().introduce_coop([&](so_5::coop_t & coop) { pinger = coop.make_agent< pinger_t >(); ponger = coop.make_agent< ponger_t >(); pinger->set_target( ponger->so_direct_mbox() ); ponger->set_target( pinger->so_direct_mbox() ); });
ãããŠãããã¹ãã·ããªãªãã®äœ¿çšãéå§ããŸãã
ãã¹ãã±ãŒã¹ã¯ãæåããæåŸãŸã§å®äºããå¿ èŠã®ããäžé£ã®çŽæ¥çãªæé ã§æ§æãããéšåã§ãã ãçŽæ¥ã·ãŒã±ã³ã¹ããããšãããã¬ãŒãºã¯ãSObjectizer-5.5.24ã§ã¯ãã¹ã¯ãªããã®ã¹ããããåå²ãã«ãŒããªãã§å³å¯ã«é£ç¶ããŠãåäœãããããšãæå³ããŸãã
ãšãŒãžã§ã³ãã®ãã¹ããäœæããããšã¯ãå®è¡ããå¿ èŠããããã¹ãã·ããªãªã®å®çŸ©ã§ãã ã€ãŸã ãã¹ãã¹ã¯ãªããã®ãã¹ãŠã®æé ã¯ãæåããæåŸãŸã§æ©èœããã¯ãã§ãã
ãããã£ãŠããã¹ãã±ãŒã¹ã§ã¯ã2段éã®ã·ããªãªãå®çŸ©ããŸãã æåã®ã¹ãããã§ã¯ãPongerãšãŒãžã§ã³ããPingã¡ãã»ãŒãžãåä¿¡ããŠââåŠçããããšã確èªããŸãã
sobj.scenario().define_step("ping") .when(*ponger & tests::reacts_to<ping>());
2çªç®ã®ã¹ãããã§ã¯ãPingerãšãŒãžã§ã³ããPongã¡ãã»ãŒãžãåä¿¡ããããšã確èªããŸãã
sobj.scenario().define_step("pong") .when(*pinger & tests::reacts_to<pong>());
ãããã®2ã€ã®æé ã¯ãã¹ãã±ãŒã¹ã«ååã§ããããã決å®åŸãã¹ã¯ãªããã®å®è¡ã«é²ã¿ãŸãã ã¹ã¯ãªãããå®è¡ãã100ããªç§ä»¥å ã«æ©èœããããã«ããŸãã
sobj.scenario().run_for(std::chrono::milliseconds(100));
2ã€ã®ãšãŒãžã§ã³ããã¡ãã»ãŒãžã亀æããã«ã¯ã100ããªç§ã§ååã§ãïŒTravis CIã®å Žåã®ããã«ããã¹ããéåžžã«é ãä»®æ³ãã·ã³å ã§å®è¡ãããå Žåã§ãïŒã ããŠããšãŒãžã§ã³ãã®èšè¿°ãééãããããã¹ãã¹ã¯ãªããã誀ã£ãŠèšè¿°ããå Žåã100ããªç§ãè¶ ãããšã©ãŒã¹ã¯ãªããã®å®äºãåŸ ã€ããšã¯æå³ããããŸããã
ãããã£ãŠãrun_forïŒïŒããæ»ã£ãåŸãã¹ã¯ãªããã¯æ£åžžã«å®äºãããã©ããã確èªã§ããŸãã ãããã£ãŠãã¹ã¯ãªããã®çµæã確èªããã ãã§ãã
REQUIRE(tests::completed() == sobj.scenario().result());
ã¹ã¯ãªãããæ£åžžã«å®äºããªãã£ãå Žåããã¹ãã±ãŒã¹ã倱æããŸãã
ããã€ãã®èª¬æãšè¿œå
ãã®ã³ãŒããéåžžã®SObjectizerå ã§å®è¡ããå ŽåïŒ
pinger_t * pinger{}; ponger_t * ponger{}; sobj.environment().introduce_coop([&](so_5::coop_t & coop) { pinger = coop.make_agent< pinger_t >(); ponger = coop.make_agent< ponger_t >(); pinger->set_target( ponger->so_direct_mbox() ); ponger->set_target( pinger->so_direct_mbox() ); });
ãã®åŸããããããPingerãšPongerã®ãšãŒãžã§ã³ãã¯ãã¡ãã»ãŒãžã亀æããintroduce_coopããæ»ãåã«äœæ¥ãå®äºããããšãã§ããŸãïŒãã«ãã¹ã¬ããã®å¥è·¡ã¯ãã®ãããªãã®ã§ãïŒã ããããtesting_env_tã®ãããã§äœæããããã¹ãç°å¢å ã§ã¯ãããã¯èµ·ãããŸãããPingerãšPongerãšãŒãžã§ã³ãã¯ããã¹ãã¹ã¯ãªãããå®è¡ãããŸã§èŸæ±åŒ·ãåŸ ã¡ãŸãã ããã¯ã©ã®ããã«èµ·ãããŸããïŒ
å®éããã¹ãç°å¢å ã§ã¯ããšãŒãžã§ã³ãã¯åçµç¶æ ã«ããããã«èŠããŸãã ã€ãŸã ç»é²åŸããããã¯SObjectizerã«ååšããŸãããã¡ãã»ãŒãžãåŠçããããšã¯ã§ããŸããã ãããã£ãŠããã¹ãã¹ã¯ãªãããå®è¡ãããåã«ããšãŒãžã§ã³ãã«å¯ŸããŠso_evt_startïŒïŒãåŒã³åºãããŸããã
run_forïŒïŒã¡ãœããã䜿çšããŠãã¹ãã¹ã¯ãªãããå®è¡ãããšããã¹ãã¹ã¯ãªããã¯ãŸããã¹ãŠã®åçµãšãŒãžã§ã³ãã解åããŸãã ãããŠãã¹ã¯ãªããã¯ããšãŒãžã§ã³ãã«äœãèµ·ãããã«é¢ããéç¥ãSObjectizerããåãåãå§ããŸãã ããšãã°ãPongerãšãŒãžã§ã³ãã¯Pingã¡ãã»ãŒãžãåä¿¡ããPongerãšãŒãžã§ã³ãã¯ã¡ãã»ãŒãžãåŠçããŸããããæåŠããŸããã§ããã
ãã®ãããªéç¥ããã¹ãã¹ã¯ãªããã«å±ãå§ãããšãã¹ã¯ãªããã¯éç¥ãæåã®ã¹ããããŸã§ãè©Šè¡ãããããšããŸãã ããã§ãPongerãPingãåä¿¡ããŠââåŠçãããšããéç¥ããããŸã-ããã¯ç§ãã¡ã«ãšã£ãŠèå³æ·±ããã®ã§ããïŒ ã¹ãããã®èª¬æããŸãã«ãããèšã£ãŠããã®ã§ããããé¢çœãããšãããããŸãïŒPongerãPingã«åå¿ãããšããããã¯åäœããŸãã ã³ãŒãã«ãããã®ïŒ
.when(*ponger & tests::reacts_to<ping>())
OK ãããã£ãŠãæåã®ã¹ãããã¯æ©èœãã次ã®ã¹ãããã«é²ã¿ãŸãã
次ã«ããšãŒãžã§ã³ããã³ã¬ãŒããã³ã«åå¿ãããšããéç¥ãæ¥ãŸãã ãããŠãããã¯ç¬¬2ã¹ããããæ©èœããããã«å¿ èŠãªãã®ã§ãã
.when(*pinger & tests::reacts_to<pong>())
OK 2çªç®ã®ã¹ãããã¯æ©èœããŸããããä»ã«äœããããŸããïŒ ãã ã€ãŸãããã¹ãã¹ã¯ãªããå šäœãå®äºããrun_forïŒïŒããå¶åŸ¡ãè¿ãããšãã§ããŸãã
ããã§ã¯ãååãšããŠããã¹ãã¹ã¯ãªããã®åäœæ¹æ³ã説æããŸãã å®éããã¹ãŠãããè€éã§ãããããè€éãªäŸãæ€èšããéã«ã¯ãããè€éãªåŽé¢ã«è§ŠããŸãã
é£äºã®å²åŠè ã®äŸ
ãã¹ããšãŒãžã§ã³ãã®ããè€éãªäŸã¯ãããç¥ãããŠããã¿ã¹ã¯ãå²åŠè ã®é£äºãã®è§£æ±ºã«èŠãããšãã§ããŸãã ã¢ã¯ã¿ãŒã«ãšã£ãŠããã®åé¡ã¯ããã€ãã®æ¹æ³ã§è§£æ±ºã§ããŸãã 次ã«ãæãäºçŽ°ãªè§£æ±ºçãæ€èšããŸãã俳åªãšå²åŠè ã®äž¡æ¹ããå²åŠè ãæŠããªããã°ãªããªã俳åªã®åœ¢ã§è¡šãããŸãã åå²åŠè ã¯ãã°ããèããŠãããå·ŠåŽã®åå²ç¹ããšãããšããŸãã ãããæåããå Žåã圌ã¯å³åŽã®åå²ãè©Šã¿ãŸãã ãããæåããå Žåãå²åŠè ã¯ãã°ããé£ã¹ããã®åŸãã©ãŒã¯ã眮ããŠèãå§ããŸãã å³åŽã®ãã©ã°ãåãããšãã§ããªãã£ãå ŽåïŒã€ãŸããå¥ã®å²åŠè ãåã£ãïŒãå²åŠè ã¯å·ŠåŽã®ãã©ã°ãè¿ãããã°ããèããŸãã ã€ãŸã ããã¯ãå²åŠè ã®äžã«ã¯ããŸãã«ãé·ã飢ããŠãããããããªããšããæå³ã§è¯ã解決çã§ã¯ãããŸããã ããããããã¯éåžžã«ç°¡åã§ãã ãŸãããšãŒãžã§ã³ãããã¹ãããèœåãå®èšŒããç¯å²ããããŸãã
Forkããã³PhilosopherãšãŒãžã§ã³ãã®å®è£ ãå«ããœãŒã¹ã³ãŒãã¯ã ããã§èŠã€ããããšãã§ããŸããèšäºã§ã¯ãã¹ããŒã¹ãç¯çŽããããã«ããããæ€èšããŸããã
ãã©ãŒã¯ã®ãã¹ã
ãšãŒãžã§ã³ããã©ãŒã¯ã®é£äºå²åŠè ããã®ãšãŒãžã§ã³ãã®æåã®ãã¹ããäœæããŸãã
ãã®ãšãŒãžã§ã³ãã¯ãåçŽãªã¹ããŒã ã«åŸã£ãŠæ©èœããŸãã 圌ã«ã¯2ã€ã®ç¶æ ããããŸãïŒFreeãšTakenã ãšãŒãžã§ã³ããFreeç¶æ ã®å ŽåããšãŒãžã§ã³ãã¯Takeã¡ãã»ãŒãžã«å¿çããŸãã ãã®å ŽåããšãŒãžã§ã³ãã¯Takenç¶æ ã«å ¥ããTakenå¿çã¡ãã»ãŒãžã§å¿çããŸãã
ãšãŒãžã§ã³ããTakenç¶æ ã«ãããšããTakeã¡ãã»ãŒãžã«å¯ŸããŠç°ãªãåå¿ãããŸãããšãŒãžã§ã³ãã®ç¶æ ã¯å€åãããBusyã¯å¿çã¡ãã»ãŒãžãšããŠéä¿¡ãããŸãã ãŸããTakenç¶æ ã§ã¯ããšãŒãžã§ã³ãã¯Putã¡ãã»ãŒãžã«å¿çããŸãããšãŒãžã§ã³ãã¯Freeç¶æ ã«æ»ããŸãã
Freeç¶æ ã§ã¯ãPutã¡ãã»ãŒãžã¯ç¡èŠãããŸãã
次ã®ãã¹ãã±ãŒã¹ã䜿çšããŠãããããã¹ãããŸãã
TEST_CASE( "fork" ) { class pseudo_philosopher_t final : public so_5::agent_t { public: pseudo_philosopher_t(context_t ctx) : so_5::agent_t{std::move(ctx)} { so_subscribe_self() .event([](mhood_t<msg_taken>) {}) .event([](mhood_t<msg_busy>) {}); } }; tests::testing_env_t sobj; so_5::agent_t * fork{}; so_5::agent_t * philosopher{}; sobj.environment().introduce_coop([&](so_5::coop_t & coop) { fork = coop.make_agent<fork_t>(); philosopher = coop.make_agent<pseudo_philosopher_t>(); }); sobj.scenario().define_step("put_when_free") .impact<msg_put>(*fork) .when(*fork & tests::ignores<msg_put>()); sobj.scenario().define_step("take_when_free") .impact<msg_take>(*fork, philosopher->so_direct_mbox()) .when_all( *fork & tests::reacts_to<msg_take>() & tests::store_state_name("fork"), *philosopher & tests::reacts_to<msg_taken>()); sobj.scenario().define_step("take_when_taken") .impact<msg_take>(*fork, philosopher->so_direct_mbox()) .when_all( *fork & tests::reacts_to<msg_take>(), *philosopher & tests::reacts_to<msg_busy>()); sobj.scenario().define_step("put_when_taken") .impact<msg_put>(*fork) .when( *fork & tests::reacts_to<msg_put>() & tests::store_state_name("fork")); sobj.scenario().run_for(std::chrono::milliseconds(100)); REQUIRE(tests::completed() == sobj.scenario().result()); REQUIRE("taken" == sobj.scenario().stored_state_name("take_when_free", "fork")); REQUIRE("free" == sobj.scenario().stored_state_name("put_when_taken", "fork")); }
ããããã®ã³ãŒããããã®ã§ããã§ã«æ確ã«ãªã£ãŠããã¯ãã®ãããã®ãã©ã°ã¡ã³ããã¹ãããããŠãéšåçã«ãããæ±ããŸãã
ããã§æåã«å¿ èŠãªããšã¯ãæ¬åœã®å²åŠè ãšãŒãžã§ã³ãã眮ãæããããšã§ãã ForkãšãŒãžã§ã³ãã¯ã誰ãããã¡ãã»ãŒãžãåä¿¡ãã誰ãã«å¿çããå¿ èŠããããŸãã ãã ãããã®ãã¹ãã±ãŒã¹ã§ã¯å®éã®å²åŠè ã䜿çšããããšã¯ã§ããŸãããå®éã®å²åŠè ãšãŒãžã§ã³ãã«ã¯ç¬èªã®åäœããžãã¯ããããã¡ãã»ãŒãžãèªåã§éä¿¡ãããããããã§ãã®ç¬ç«æ§ã劚ããããŸãã
ãããã£ãŠã ã¢ãã¯ãè¡ããŸãã æ¬ç©ã®å²åŠè ã®ä»£ããã«ãããã®ä»£ããã玹ä»ããŸãã空ã®ãšãŒãžã§ã³ãã¯ãäœãéä¿¡ãããåä¿¡ããã¡ãã»ãŒãžã®ã¿ãéä¿¡ããŸãã ããã¯ãã³ãŒãã«å®è£ ãããç䌌å²åŠè ã§ãã
class pseudo_philosopher_t final : public so_5::agent_t { public: pseudo_philosopher_t(context_t ctx) : so_5::agent_t{std::move(ctx)} { so_subscribe_self() .event([](mhood_t<msg_taken>) {}) .event([](mhood_t<msg_busy>) {}); } };
次ã«ãForkãšãŒãžã§ã³ããšPseudoPhilospherãšãŒãžã§ã³ãããã³ã©ãã¬ãŒã·ã§ã³ãäœæãããã¹ãã±ãŒã¹ã®å 容ã®æ±ºå®ãéå§ããŸãã
ã¹ã¯ãªããã®æåã®ã¹ãããã¯ãFreeç¶æ ïŒããã³ãããåæç¶æ ïŒã«ããForkãPutã¡ãã»ãŒãžã«å¿çããªãããšã確èªããããšã§ãã ãã®ãã§ãã¯ã®èšè¿°æ¹æ³ã¯æ¬¡ã®ãšããã§ãã
sobj.scenario().define_step("put_when_free") .impact<msg_put>(*fork) .when(*fork & tests::ignores<msg_put>());
æåã«æ³šç®ãããã®ã¯ãã€ã³ãã¯ãæ§é ã§ãã
ãšãŒãžã§ã³ãForkã¯èªåã§äœããããçä¿¡ã¡ãã»ãŒãžã«ã®ã¿åå¿ããããã圌女ãå¿ èŠã§ãã ãããã£ãŠã誰ãããšãŒãžã§ã³ãã«ã¡ãã»ãŒãžãéä¿¡ããå¿ èŠããããŸãã ãããã誰ã§ããïŒ
ãããŠãããã«ã¹ã¯ãªããã®ã¹ãããããããã€ã³ãã¯ããéããŠãããéããŸãã å®éã圱é¿ã¯éåžžã®éä¿¡æ©èœã«é¡äŒŒããŠããŸãïŒåœ¢åŒã¯åãã§ãïŒã
ããŠãã¹ã¯ãªããã¹ãããèªäœã圱é¿ãéããŠã¡ãã»ãŒãžãéä¿¡ããŸãã ãããããã€åœŒã¯ãããããŸããïŒ
ãããŠã圌ã«é çªãæ¥ãã圌ã¯ãããããã§ãããã ã€ãŸã ã¹ã¯ãªããã®ã¹ããããæåã®å Žåãrun_forãå ¥åããçŽåŸã«åœ±é¿ãå®è¡ãããŸãã ã¹ã¯ãªããã®ã¹ããããæåã§ã¯ãªãå Žåãåã®ã¹ããããæ©èœãããšããã«åœ±é¿ãå®è¡ãããã¹ã¯ãªããã¯æ¬¡ã®ã¹ãããã®åŠçã«é²ã¿ãŸãã
ããã§èª¬æããå¿ èŠããã2çªç®ã®ããšã¯ãåŒã³åºãç¡èŠã§ãã ãã®ãã«ããŒé¢æ°ã¯ããšãŒãžã§ã³ããã¡ãã»ãŒãžã®åŠçãéå§ãããšã¹ããããããªã¬ãŒãããããšã瀺ããŠããŸãã ã€ãŸã ãã®å ŽåãForkãšãŒãžã§ã³ãã¯Putã¡ãã»ãŒãžã®åŠçãæåŠããå¿ èŠããããŸãã
ãã¹ãã·ããªãªã®ãã1ã€ã®ã¹ããããããã«è©³ããèããŠã¿ãŸãããã
sobj.scenario().define_step("take_when_free") .impact<msg_take>(*fork, philosopher->so_direct_mbox()) .when_all( *fork & tests::reacts_to<msg_take>() & tests::store_state_name("fork"), *philosopher & tests::reacts_to<msg_taken>());
ãŸããããã§ã¯whenã§ã¯ãªãwhen_allã衚瀺ãããŸãã ããã¯ãã¹ããããããªã¬ãŒããã«ã¯ãããã€ãã®æ¡ä»¶ãäžåºŠã«æºããå¿ èŠãããããã§ãã ãã©ãŒã¯ãšãŒãžã§ã³ãã¯TakeãåŠçããå¿ èŠããããŸãã ãããŠãå²åŠè ã¯Takenã®å¿çãåŠçããå¿ èŠããããŸãã ãããã£ãŠãwhenã§ã¯ãªãwhen_allãèšè¿°ããŸãã ãšããã§ãwhen_anyããããŸãããä»æ¥æ€èšããäŸã§ã¯ã圌ãšã¯äŒããŸããã
第äºã«ããã€ã¯åŠçã®åŸããã©ãŒã¯ãšãŒãžã§ã³ãããã€ã¯ç¶æ ã«ãªã£ãŠããããšã確èªããå¿ èŠããããŸãã æ€èšŒã¯æ¬¡ã®ããã«è¡ããŸãããŸããForkãšãŒãžã§ã³ããTakeã®åŠçãçµäºãããšããã«ãã¿ã°ã¿ã°ãforkãã䜿çšããŠçŸåšã®ç¶æ ã®ååãä¿åããå¿ èŠãããããšã瀺ããŸãã ãã®æ§é ã¯ããšãŒãžã§ã³ãã®ç¶æ åãä¿æããã ãã§ãã
& tests::store_state_name("fork")
ãããŠãã¹ã¯ãªãããæ£åžžã«å®äºãããããã®ä¿åãããååã確èªããŸãã
REQUIRE("taken" == sobj.scenario().stored_state_name("take_when_free", "fork"));
ã€ãŸã ã¹ã¯ãªããã«åãåãããŸããtake_when_freeãšããååã®ã¹ãããã®forkã¿ã°ã§ä¿åãããååãæå®ãããã®ååãæåŸ ãããå€ãšæ¯èŒããŸãã
ããã§ããããããForkãšãŒãžã§ã³ãã®ãã¹ãã±ãŒã¹ã§æ³šæã§ããããšã¯ãã¹ãŠã§ãã èªè ã«è³ªåãããå Žåã¯ãã³ã¡ã³ãã§è³ªåããŠãã ãããåãã§ãçãããŸãã
å²åŠè ã®ããã®æåããã¹ã¯ãªãããã¹ã
å²åŠè ãšãŒãžã§ã³ãã«ã€ããŠã¯ã1ã€ã®ãã¹ãã±ãŒã¹ã®ã¿ãæ€èšããŸã-å²åŠè ããã©ãŒã¯ãé£ã¹ãŠé£ã¹ãããšãã§ããå Žåã
ãã®ãã¹ãã±ãŒã¹ã¯æ¬¡ã®ããã«ãªããŸãã
TEST_CASE( "philosopher (takes both forks)" ) { tests::testing_env_t sobj{ [](so_5::environment_params_t & params) { params.message_delivery_tracer( so_5::msg_tracing::std_cout_tracer()); } }; so_5::agent_t * philosopher{}; so_5::agent_t * left_fork{}; so_5::agent_t * right_fork{}; sobj.environment().introduce_coop([&](so_5::coop_t & coop) { left_fork = coop.make_agent<fork_t>(); right_fork = coop.make_agent<fork_t>(); philosopher = coop.make_agent<philosopher_t>( "philosopher", left_fork->so_direct_mbox(), right_fork->so_direct_mbox()); }); auto scenario = sobj.scenario(); scenario.define_step("stop_thinking") .when( *philosopher & tests::reacts_to<philosopher_t::msg_stop_thinking>() & tests::store_state_name("philosopher") ) .constraints( tests::not_before(std::chrono::milliseconds(250)) ); scenario.define_step("take_left") .when( *left_fork & tests::reacts_to<msg_take>() ); scenario.define_step("left_taken") .when( *philosopher & tests::reacts_to<msg_taken>() & tests::store_state_name("philosopher") ); scenario.define_step("take_right") .when( *right_fork & tests::reacts_to<msg_take>() ); scenario.define_step("right_taken") .when( *philosopher & tests::reacts_to<msg_taken>() & tests::store_state_name("philosopher") ); scenario.define_step("stop_eating") .when( *philosopher & tests::reacts_to<philosopher_t::msg_stop_eating>() & tests::store_state_name("philosopher") ) .constraints( tests::not_before(std::chrono::milliseconds(250)) ); scenario.define_step("return_forks") .when_all( *left_fork & tests::reacts_to<msg_put>(), *right_fork & tests::reacts_to<msg_put>() ); scenario.run_for(std::chrono::seconds(1)); REQUIRE(tests::completed() == scenario.result()); REQUIRE("wait_left" == scenario.stored_state_name("stop_thinking", "philosopher")); REQUIRE("wait_right" == scenario.stored_state_name("left_taken", "philosopher")); REQUIRE("eating" == scenario.stored_state_name("right_taken", "philosopher")); REQUIRE("thinking" == scenario.stored_state_name("stop_eating", "philosopher")); }
ããªãããªã¥ãŒã ããããŸãããäºçŽ°ãªããšã§ãã æåã«ãå²åŠè ãæèãçµäºããé£ç©ã®æºåãå§ããããšã確èªããŸãã 次ã«ã圌ãå·Šã®ãã©ãŒã¯ããšãããšããããšã確èªããŸãã 次ã«ã圌ã¯å³ã®ãã©ãŒã¯ãåãããã«ããŠãã ããã ãããã圌ã¯ãã®æŽ»åãé£ã¹ãŠãããã¹ãã§ãã ãã®åŸã圌ã¯äž¡æ¹ã®ãã©ãŒã¯ãåããªããã°ãªããŸããã
äžè¬çã«ããã¹ãŠã¯ç°¡åã§ãã ãã ãã次ã®2ã€ã®ããšã«æ³šæããå¿ èŠããããŸãã
æåã«ãtesting_env_tã¯ã©ã¹ã¯ããã®ãããã¿ã€ãã§ããwrapped_env_tãšåæ§ã«ãSObjectizer Environmentãã«ã¹ã¿ãã€ãºã§ããŸãã ããã䜿çšããŠãã¡ãã»ãŒãžé ä¿¡ãã¬ãŒã¹ã¡ã«ããºã ãæå¹ã«ããŸãã
tests::testing_env_t sobj{ [](so_5::environment_params_t & params) { params.message_delivery_tracer( so_5::msg_tracing::std_cout_tracer()); } };
ãã®ã¡ã«ããºã ã«ãããã¡ãã»ãŒãžé ä¿¡ã®ããã»ã¹ããèŠèŠåãããããšãã§ããŸããããã«ããããšãŒãžã§ã³ãã®åäœãåŠçããã®ã«åœ¹ç«ã¡ãŸãïŒããã«ã€ããŠã¯æ¢ã«è©³ãã説æããŸãã ïŒã
次ã«ããšãŒãžã§ã³ãPhilosopherã¯ããã«ã§ã¯ãªãããã°ããããŠããäžé£ã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãã ãããã£ãŠãåäœãéå§ããã«ã¯ããšãŒãžã§ã³ãã¯ä¿çäžã®StopThinkingã¡ãã»ãŒãžãèªåã§éä¿¡ããå¿ èŠããããŸãã ãããã£ãŠããã®ã¡ãã»ãŒãžã¯æ°ããªç§åŸã«ãšãŒãžã§ã³ãã«å±ãã¯ãã§ãã ç¹å®ã®ã¹ãããã«å¿ èŠãªå¶éãèšå®ããããšã§ç€ºããŸãã
scenario.define_step("stop_thinking") .when( *philosopher & tests::reacts_to<philosopher_t::msg_stop_thinking>() & tests::store_state_name("philosopher") ) .constraints( tests::not_before(std::chrono::milliseconds(250)) );
ã€ãŸã ããã§ã¯ãå²åŠè ãšãŒãžã§ã³ãã®StopThinkingãžã®å¿çã«ã¯é¢å¿ããªãããã®ã¹ãããã®åŠçéå§ãã250ms以å ã«çºçããå¿çã«ã®ã¿é¢å¿ããããšèšããŸãã
not_beforeã¿ã€ãã®å¶éã¯ãæå®ãããã¿ã€ã ã¢ãŠãã®æéãåããåã«çºçãããã¹ãŠã®ã€ãã³ããç¡èŠããå¿ èŠãããããšãã¹ã¯ãªããã«ç€ºããŸãã
ãŸããnot_afterãšãã圢åŒã®å¶éããããŸããéã®æ¹æ³ã§æ©èœããŸããæå®ãããã¿ã€ã ã¢ãŠããæéåãã«ãªããŸã§çºçããã€ãã³ãã®ã¿ãèæ ®ãããŸãã
not_beforeå¶çŽãšnot_afterå¶çŽã¯çµã¿åãããããšãã§ããŸãã次ã«äŸã瀺ããŸãã
.constraints( tests::not_before(std::chrono::milliseconds(250)), tests::not_after(std::chrono::milliseconds(1250)))
ãã ãããã®å ŽåãSObjectizerã¯æå®ãããå€ã®æŽåæ§ããã§ãã¯ããŸããã
ã©ããã£ãŠãããå®è£ ããŸãããïŒ
ã©ã®ããã«ãã¹ãŠãæ©èœããããã«ãªã£ããã«ã€ããŠãããã€ãã®èšèãè¿°ã¹ãããšæããŸãã å®éãæŠããŠããåççã«ãšãŒãžã§ã³ãããã¹ãããæ¹æ³ããšãã1ã€ã®å€§ããªã€ããªãã®ãŒã®åé¡ã«çŽé¢ããŸããã
ãããŠããã¹ãã®ã€ããªãã®ãŒã«é¢ããŠãããªãã奜ããªããã«æãåºãããšãã§ãããªããç¶æ³ã¯å®è£ ã«é¢ããŠããè€éã§ããã ãŸããSObjectizerã®å éšãæ ¹æ¬çã«å€æŽããå¿ èŠã®ãªããœãªã¥ãŒã·ã§ã³ãèŠã€ããå¿ èŠããããŸããã ãããŠã第äºã«ãããã¯äºèŠå¯èœãªéåžžã«æãŸããçæéã§å®è£ ã§ãããœãªã¥ãŒã·ã§ã³ã§ãããšæ³å®ãããŠããŸããã
竹ãåžããšããå°é£ãªããã»ã¹ã®çµæãšããŠã解決çãèŠã€ãããŸããã ãã®ãããå®éã«ã¯ãSObjectizerã®éåžžã®åäœã«1ã€ã®å°ããªã€ãããŒã·ã§ã³ã®ã¿ãå°å ¥ããå¿ èŠããããŸããã ãããŠããœãªã¥ãŒã·ã§ã³ã®åºæ¬ã¯ã ã¡ãã»ãŒãžã®ãšã³ãããŒãã¡ã«ããºã ã§ããããã¯ãããŒãžã§ã³5.5.23ã§è¿œå ããããã®ã§ãæ¢ã«èª¬æããŸãã ã
ãã¹ãç°å¢å ã§ã¯ãéä¿¡ãããåã¡ãã»ãŒãžã¯ç¹å¥ãªãšã³ãããŒãã§ã©ãããããŸãã ã¡ãã»ãŒãžãå«ããšã³ãããŒããåŠçã®ããã«ãšãŒãžã§ã³ãã«æž¡ãããïŒãŸãã¯ãéã«ãšãŒãžã§ã³ãã«ãã£ãŠæåŠãããïŒãšããã¹ãã·ããªãªã¯ãããèªèããŸãã ãšã³ãããŒãã®ãããã§ããã¹ãã¹ã¯ãªããã¯äœãèµ·ãã£ãŠããããææ¡ããã¹ã¯ãªããããåäœãããã¹ããããå€æã§ããŸãã
ããããSObjectizerã«åã¡ãã»ãŒãžãç¹å¥ãªãšã³ãããŒãã§ã©ãããããæ¹æ³ã¯ïŒ
ããã¯èå³æ·±ã質åã§ããã 圌ã¯æ¬¡ã®ããã«æ±ºå®ããŸãããevent_queue_hookã®ãããªãã®ãçºæãããŸããã ããã¯ãon_bindãšon_unbindã®2ã€ã®ã¡ãœãããæã€ç¹å¥ãªãªããžã§ã¯ãã§ãã
ãšãŒãžã§ã³ããç¹å®ã®ãã£ã¹ãããã£ã«ãã€ã³ãããããšããã£ã¹ãããã£ã¯ãšãŒãžã§ã³ãevent_queueããšãŒãžã§ã³ãã«çºè¡ããŸãã ãã®event_queueãä»ããŠããšãŒãžã§ã³ããžã®èŠæ±ã¯å¿ èŠãªãã¥ãŒã«å ¥ãããã£ã¹ãããã£ãåŠçã§ããããã«ãªããŸãã ãšãŒãžã§ã³ããSObjectizerå ã§å®è¡ãããå Žåãevent_queueãžã®ãã€ã³ã¿ãŒããããŸãã ãšãŒãžã§ã³ããSObjectizerããåé€ããããšãevent_queueãžã®ãã€ã³ã¿ãŒã¯ç¡å¹ã«ãªããŸãã
ãã®ãããããŒãžã§ã³5.5.24以éããšãŒãžã§ã³ãã¯event_queueãåä¿¡ãããšãevent_queue_hookã®on_bindã¡ãœãããåŒã³åºãå¿ èŠããããŸãã ãšãŒãžã§ã³ããåãåã£ããã€ã³ã¿ãŒãevent_queueã«æž¡ãå Žæã ãŸããevent_queue_hookã¯ãå¿çã§åããã€ã³ã¿ãŒãŸãã¯å¥ã®ãã€ã³ã¿ãŒãè¿ãããšãã§ããŸãã ãŸãããšãŒãžã§ã³ãã¯æ»ãå€ã䜿çšããå¿ èŠããããŸãã
SObjectizerãããšãŒãžã§ã³ããåé€ããå Žåãevent_queue_hookã§on_unbindãåŒã³åºãå¿ èŠããããŸãã on_unbindã§ã¯ããšãŒãžã§ã³ãã¯on_bindã¡ãœããã«ãã£ãŠè¿ãããå€ãæž¡ããŸãã
ãã®ãããã³å šäœã¯SObjectizerå ã§å®è¡ããããŠãŒã¶ãŒã«ã¯äœã衚瀺ãããŸããã ãããŠãååãšããŠãããªãã¯ããã«ã€ããŠå šãç¥ããªããããããŸããã ãã ããåãtesting_env_tã§ããSObjectizerã®ãã¹ãç°å¢ã¯ãevent_queue_hookãæ£ç¢ºã«æŽ»çšããŸãã testing_env_tå ã«ãevent_queue_hookã®ç¹å¥ãªå®è£ ãäœæãããŸããon_bindã®ãã®å®è£ ã¯ãåevent_queueãç¹å¥ãªãããã·ãªããžã§ã¯ãã«ã©ããããŸãããããŠããã§ã«ãã®ãããã·ãªããžã§ã¯ãã¯ããšãŒãžã§ã³ãã«éä¿¡ãããã¡ãã»ãŒãžãç¹å¥ãªãšã³ãããŒãã«å ¥ããŸãã
ããããããã ãã§ã¯ãããŸããããã¹ãç°å¢ã§ã¯ããšãŒãžã§ã³ããåçµããå¿ èŠãããããšãæãåºããŠãã ãããããã¯ãåè¿°ã®ãããã·ãªããžã§ã¯ããéããŠãå®è£ ãããŸãããã¹ãã¹ã¯ãªãããå®è¡ãããŠããªãéããããã·ãªããžã§ã¯ãã¯èªå® ã®ãšãŒãžã§ã³ãã«éä¿¡ãããã¡ãã»ãŒãžãä¿åããŸãããã ããã¹ã¯ãªãããå®è¡ããããšããããã·ãªããžã§ã¯ãã¯ä»¥åã«èç©ããããã¹ãŠã®ã¡ãã»ãŒãžããšãŒãžã§ã³ãã®çŸåšã®ã¡ãã»ãŒãžãã¥ãŒã«è»¢éããŸãã
ãããã«
çµè«ãšããŠã2ã€ã®ããšãèšããããšæããŸãã
æåã«ãSObjectizerã§ãšãŒãžã§ã³ãããã¹ãããæ¹æ³ã«é¢ãããã¥ãŒãå®è£ ããŸãããç§ã®æèŠã¯ãè¯ãããŒã«ã¢ãã«ãããŸãå€ããªãããã§ããç§ãã¡ã¯ãæ¹åã«èŠããAkka.Testingããã ããAkkaãšSObjectizerã¯ããŸãã«ãç°ãªããããAkkaã§æ©èœããã¢ãããŒããSObjectizerã«ç§»æ€ããããšã¯ã§ããŸããããŸããC ++ã¯Scala / Javaã§ã¯ãããŸãããScalaã§ã¯ãå çã«é¢é£ããããã€ãã®ããšããªãã¬ã¯ã·ã§ã³ã«ãã£ãŠå®è¡ã§ããŸãããã®ãããSObjectizerã«åœãŠã¯ãŸãã¢ãããŒããèãåºãå¿ èŠããããŸããã
ããŒãžã§ã³5.5.24ã§ã¯ãæåã®å®éšçãªå®è£ ãå©çšå¯èœã«ãªããŸããããã£ãšããªãã¯ãã£ãšè¯ãã§ããã§ããããããããäœãæçšã§ãããäœã圹ã«ç«ããªã空æ³ã§ããããç解ããæ¹æ³ã¯ïŒæ®å¿µãªãããæ¹æ³ã¯ãããŸãããå®éã«äœãèµ·ããããèŠãŠãè©ŠããŠã¿ãå¿ èŠããããŸãã
ããã§ãç§ãã¡ã¯ããªããè©ŠããŠã¿ãããšãã§ããæå°éã®ããŒãžã§ã³ãäœããŸãããçã®ããã«ç§ãã¡ãææ¡ããããšïŒããªãã®å°è±¡ãè©ŠããŠã¿ãŠãç§ãã¡ãšå ±æããŠãã ãããäœã奜ãã§ãäœã奜ãã§ã¯ãªãã£ãã®ã§ããïŒãã¶ãäœããæ¬ ããŠããŸããïŒ
第äºã«ã2017幎ã®åãã«èšãããèšèãããã«é¢é£ããããã«ãªããŸããã
⊠, , , . - â . . . : , .ã¢ã¯ã¿ãŒã®ãã¹ãã«é¢ããŠã¯ãäžèšã®ãã¹ãŠãããã«éèŠã§ãããããã£ãŠãã¢ã¯ã¿ãŒãã¬ãŒã ã¯ãŒã¯ãèªåã§éžæãããšãã¯ããã®äžã«ãããã®ãšããã§ãªããã®ã«æ³šæããŠãã ãããããšãã°ããã¹ããç°¡çŽ åããããã®ããŒã«ãããããã§ã«ãããŸã:)
, , , â , .
ãããã£ãŠãæ¢æã®ã¢ã¯ã¿ãŒãã¬ãŒã ã¯ãŒã¯ãæ¢ããŠãã人ãžã®ç§ã®ã¢ããã€ã¹ïŒã¢ã€ãã¢ã®ç¬åµæ§ãšäŸã®çŸããã ãã§ãªã泚æãæã£ãŠãã ããããŸããã¢ããªã±ãŒã·ã§ã³ã§äœãèµ·ãã£ãŠããã®ããææ¡ããã®ã«åœ¹ç«ã€ããããçš®é¡ã®è£å©çãªãã®ãèŠãŠãã ãããããšãã°ãçŸåšå éšã«ããã¢ã¯ã¿ã®æ°ããã¥ãŒã®ãµã€ãºãã¡ãã»ãŒãžãåä¿¡è ã«å±ããªãå Žåãã©ãã«è¡ãã®ãã調ã¹ãã«ã¯...ãã®ãããªãã®ãæäŸããããã¯ããªãã®ããã«ç°¡åã«ãªããŸããããã§ãªãå Žåã¯ãããã«äœæ¥ãå¿ èŠã«ãªããŸãã