ãã®ãã¿ãŒã³ã®äž»é¡ã«ã¯å€ãã®ããªãšãŒã·ã§ã³ããããŸãããã»ãšãã©ã®äŸã¯ãã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã«ã¯é©ããŠããŸããã
ãã®èšäºã§ã¯ããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã§ãã¿ãŒã³ãé©çšããçµéšãå
±æããééããäž»ãªåé¡ã«ã€ããŠèª¬æããŸãã
ãã®èšäºã®ç®çã¯ããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®äœææã«çºçããå¯èœæ§ã®ããåé¡ã«éçºè
ã®æ³šæãåŒãããšã§ãã ãã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ããŒãã³ãéã®éä¿¡ã®å®è£
ã«ãããèœãšãç©Žãç¹å®ããŸãã
æ¢è£œã®ãœãªã¥ãŒã·ã§ã³ãå¿
èŠãªå Žåã¯ã
2009幎5æããboostã«å«ãŸããŠããSignals2ã©ã€ãã©ãªã«æ³šæããŠãã ããã
æ¢è£œã§äœ¿çšã§ãããœãªã¥ãŒã·ã§ã³ãæäŸããããšã¯ããŠããŸããã ããã«ãããããããè³æãèªãã åŸã¯ãäœããã®çç±ã§äœ¿çšã§ããªããŸãã¯æãŸãããªããããžã§ã¯ãïŒãã©ã€ããŒãäœã¬ãã«ã¢ããªã±ãŒã·ã§ã³ãªã©ïŒã§ãµãŒãããŒãã£ã®ã©ã€ãã©ãªã䜿çšããã«å®è¡ã§ããŸãã
ãµããžã§ã¯ããšãªã¢
俳åª
NotificationSender-ã¡ãã»ãŒãžãéä¿¡ãããªããžã§ã¯ãã
éåžžãããã¯ç¶æ
ã®å€åãéç¥ããã¯ãŒã¯ãããŒã§ããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã«è¡šç€ºããå¿
èŠããããŸãã
NotificationListener-éç¥åŠçãå®è£
ãããªããžã§ã¯ãã
éåžžãããã¯ãããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã«é¢é£ä»ãããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®äžéšã®è¡šç€ºãå¶åŸ¡ãããªããžã§ã¯ãã§ãã
ãã®ãããªãªããžã§ã¯ãã¯å€æ°ååšããå¯èœæ§ããããŸãããåçã«æ¥ç¶/åæã§ããŸãïŒããšãã°ãã¿ã¹ã¯ã®è©³çŽ°ã衚瀺ããããã€ã¢ãã°ããã¯ã¹ãéãïŒ
NotificationDispatcher-ãµãã¹ã¯ã©ã€ããŒãšã¡ãŒãªã³ã°ãªã¹ãã管çãããªããžã§ã¯ãã
ãªããžã§ã¯ãéã®çžäºäœçš
ãã¹ãŠã®ãµãã¹ã¯ã©ã€ããŒãžã®ã¡ãã»ãŒãžã®é
åžã
ãµãã¹ã¯ãªãã·ã§ã³ããµãã¹ã¯ã©ã€ã/çµäºããããã»ã¹ã
ãªããžã§ã¯ãã®å¯¿åœã
ãã®èšäºã§ã¯ãåæã¡ãã»ãŒãžã³ã°æ¹åŒã«ã€ããŠèª¬æããŸãã ã€ãŸããSendMessageé¢æ°ã®åŒã³åºãã¯åæçã«è¡ããããã®ã¡ãœãããåŒã³åºãã¹ã¬ããã¯ããã¹ãŠã®ãµãã¹ã¯ã©ã€ããŒãã¡ãã»ãŒãžåŠçãå®äºãããŸã§åŸ
æ©ããŸãã å Žåã«ãã£ãŠã¯ããã®ã¢ãããŒãã¯éåæã¡ãŒã«éä¿¡ããã䟿å©ã§ãããåæã«è³Œèªè§£é€ã«ã¯å°é£ã䌎ããŸãã
æãåçŽãªã·ã³ã°ã«ã¹ã¬ããå®è£
typedef unsigned __int64 SubscriberId; class CSubscriber { public: virtual ~CSubscriber(){} virtual void MessageHandler(void* pContext) = 0; SubscriberId GetSubscriberId() {return (SubscriberId)this;} }; class CDispatcher { private: typedef std::vector<CSubscriber*> CSubscriberList; public: SubscriberId Subscribe(CSubscriber* pNewSubscriber) { for(size_t i = 0; i < m_SubscriberList.size(); ++i) { if(m_SubscriberList[i]->GetSubscriberId() == pNewSubscriber->GetSubscriberId()) { return 0; } } m_SubscriberList.push_back(pNewSubscriber); return pNewSubscriber->GetSubscriberId(); } bool Unsubscribe(SubscriberId id) { for(size_t i = 0; i < m_SubscriberList.size(); ++i) { if(m_SubscriberList[i]->GetSubscriberId() == id) { m_SubscriberList.erase(m_SubscriberList.begin() + i); return true; } } return false; } void SendMessage(void* pContext) { for(size_t i = 0; i < m_SubscriberList.size(); ++i) { m_SubscriberList[i]->MessageHandler(pContext); } } private: CSubscriberList m_SubscriberList; };
ããã§ããµãã¹ã¯ã©ã€ãã®äžæã®èå¥åã¯ãµãã¹ã¯ã©ã€ããªããžã§ã¯ãã®ã¢ãã¬ã¹ã§ããGetSubscriberIdé¢æ°ã¯ãåå€æã«é¢ä¿ãªããåžžã«1ã€ã®ãµãã¹ã¯ã©ã€ããªããžã§ã¯ãã«å¯ŸããŠåãå€ãè¿ããŸãã
䜿çšäŸ
class CListener: public CSubscriber { virtual void MessageHandler(void* pContext) { wprintf(L"%d\n", *((int*)pContext)); } }; int _tmain(int argc, _TCHAR* argv[]) { CDispatcher Dispatcher; CListener Listener1; CListener Listener2; Dispatcher.Subscribe(&Listener1); Dispatcher.Subscribe(&Listener2); for(int i = 0; i < 5; ++i) { Dispatcher.SendMessage(&i); } Dispatcher.Unsubscribe(Listener2.GetSubscriberId()); Dispatcher.Unsubscribe(Listener1.GetSubscriberId()); return 0; }
ã¡ãã»ãŒãžãã³ãã©ãŒå
ã®ãµãã¹ã¯ã©ã€ããŒã®ç¡å¹å
ãã®äŸã§ã¯ããã«ãã¹ã¬ããã«é¢é£ããªãåé¡ããããŸãã ãã®åé¡ã¯ãMessageHandlerãã³ãã©ãŒå
ã§ãµãã¹ã¯ã©ã€ãã解é€ããããšãããšçŸããŸãã ãã®åé¡ã¯ãMessageHandlerãåŒã³åºãåã«ãµãã¹ã¯ã©ã€ããŒã®ãªã¹ããã³ããŒããããšã§è§£æ±ºãããŸãã
ãã«ãã¹ã¬ããç°å¢ãžã®ç§»è¡
1ã€ã®ã¹ã¬ããã§ããã®ãããªã³ãŒãã¯éåžžã«å®å®ããŠåäœããŸãã
è€æ°ã®ã¹ã¬ãããåäœãããšãã«äœãèµ·ãããèŠãŠã¿ãŸãããã
CDispatcher g_Dispatcher; DWORD WINAPI WorkingThread(PVOID pParam) { for(int i = 0;;++i) { g_Dispatcher.SendMessage(&i); } }; int _tmain(int argc, _TCHAR* argv[]) { ::CreateThread(NULL, 0, WorkingThread, NULL, 0, NULL); CListener Listener1; CListener Listener2; for(;;) { g_Dispatcher.Subscribe(&Listener1); g_Dispatcher.Subscribe(&Listener2); g_Dispatcher.Unsubscribe(Listener1.GetSubscriberId()); g_Dispatcher.Unsubscribe(Listener2.GetSubscriberId()); } return 0; }
é
ããæ©ãããã¯ã©ãã·ã¥ãçºçããŸãã
åé¡ã¯ããµãã¹ã¯ã©ã€ããŒã®è¿œå /åé€ãšéç¥ã®éä¿¡ã§ãïŒãã®äŸã§ã¯ãCDispatcher :: m_SubscriberListãžã®ãã«ãã¹ã¬ããã¢ã¯ã»ã¹ïŒã
ããã§ã¯ããµãã¹ã¯ã©ã€ããŒã®ãªã¹ããžã®ã¢ã¯ã»ã¹ãåæããå¿
èŠããããŸãã
ãµãã¹ã¯ã©ã€ããŒãªã¹ãã¢ã¯ã»ã¹åæ
class CDispatcher { private: typedef std::vector<CSubscriber*> CSubscriberList; public: SubscriberId Subscribe(CSubscriber* pNewSubscriber) { CScopeLocker ScopeLocker(m_Lock); for(size_t i = 0; i < m_SubscriberList.size(); ++i) { if(m_SubscriberList[i]->GetSubscriberId() == pNewSubscriber->GetSubscriberId()) { return 0; } } m_SubscriberList.push_back(pNewSubscriber); return pNewSubscriber->GetSubscriberId(); } bool Unsubscribe(SubscriberId id) { CScopeLocker ScopeLocker(m_Lock); for(size_t i = 0; i < m_SubscriberList.size(); ++i) { if(m_SubscriberList[i]->GetSubscriberId() == id) { m_SubscriberList.erase(m_SubscriberList.begin() + i); return true; } } return false; } void SendMessage(void* pContext) { CScopeLocker ScopeLocker(m_Lock); for(size_t i = 0; i < m_SubscriberList.size(); ++i) { m_SubscriberList[i]->MessageHandler(pContext); } } private: CSubscriberList m_SubscriberList; CLock m_Lock; };
ã¢ã¯ã»ã¹åæã¯ãåæãªããžã§ã¯ãïŒã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ãŸãã¯ãã¥ãŒããã¯ã¹ïŒã䜿çšããŠå®è£
ãããŸããã
移æ€æ§ãé«ããããã«ããŸãèµ·ããŠããããšã®æ¬è³ªããæ°ãæ£ãããªãããã«ãEnterCriticalSectionãªã©ã®ãã©ãããã©ãŒã äŸåã®é¢æ°ãžã®çŽæ¥åŒã³åºãããæœè±¡åããŸãã ãããè¡ãã«ã¯ãCLockã¯ã©ã¹ã䜿çšããŸãã
C ++äŸå€ã«å¯Ÿããèæ§ãåŸãã«ã¯ãRAIIãã¯ãããžãã€ãŸãCScopeLockerã¯ã©ã¹ã䜿çšãããšäŸ¿å©ã§ããCScopeLockerã¯ã©ã¹ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã§åæãªããžã§ã¯ãããã£ããã£ãããã¹ãã©ã¯ã¿ã§è§£æŸããŸãã
ãã®ãããªå®è£
ã§ã¯ãããã°ã©ã ã¯èœã¡ãŸããããå¥ã®äžå¿«ãªç¶æ³ãåŸ
ã£ãŠããŸãã
ãããããã¯ãšã®æŠã
ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ãå®è¡ããç¹å®ã®ã¹ã¬ãããããããã®ã¿ã¹ã¯ã®é²è¡ç¶æ³ã衚瀺ããããŠã£ã³ããŠããããšããŸãã
éåžžãã¹ã¬ããã¯ãŠã£ã³ããŠã¯ã©ã¹ã«éç¥ãéä¿¡ãããŠã£ã³ããŠã¯ã©ã¹ã¯ãŠã£ã³ããŠã¡ãã»ãŒãžããã·ãŒãžã£ã®ã³ã³ããã¹ãã§äœããã®ã¢ã¯ã·ã§ã³ãéå§ããSendMessageã·ã¹ãã é¢æ°ãåŒã³åºããŸãã
SendMessageã·ã¹ãã é¢æ°ã¯ãããã¯ãããŠããããŠã£ã³ããŠã¹ã¬ããã«ã¡ãã»ãŒãžãéä¿¡ããåŠçãåŸ
æ©ããŸãã
ãªã¹ããŒãªããžã§ã¯ãã®æ¥ç¶/åæããŠã£ã³ããŠããã·ãŒãžã£ã®ã³ã³ããã¹ãïŒãŠã£ã³ããŠã¹ã¬ããå
ïŒã§ãçºçããå Žåãã¹ã¬ããã®çžäºãããã¯ïŒãããããããããã¯ïŒãå¯èœã§ãã
ãã®ãããªãããããã¯ã¯ããããŸãã«ããåçŸã§ããŸããïŒSubscribe / UnsubscribeãåŒã³åºããåæã«å¥ã®ã¹ã¬ããã§MessageHandlerãåŒã³åºããšãïŒ
次ã®ã³ãŒãã¯ãSendMessageã·ã¹ãã é¢æ°ã®ããããã³ã°åŒã³åºãããšãã¥ã¬ãŒãããŸãã
CDispatcher g_Dispatcher; CLock g_Lock; class CListener: public CSubscriber { virtual void MessageHandler(void* pContext) {
åé¡ã¯ãã¡ã€ã³ã¹ã¬ãããg_Lockã°ããŒãã«åæãªããžã§ã¯ãããã£ããã£ãïŒãŠã£ã³ããŠããã·ãŒãžã£ãšåæ§ã«ããŠã£ã³ããŠã¹ããªãŒã ã®ã³ã³ããã¹ãã§å®è¡ããïŒãSubscribe / Unsubscribeã¡ãœãããåŒã³åºãããšã§ããå
éšã§2çªç®ã®CDispatcher :: m_Lockåæãªããžã§ã¯ãããã£ããã£ããããšããŸãã
ãã®æç¹ã§ãã¯ãŒã«ãŒã¹ã¬ããã¯éç¥ãéä¿¡ããŠãCDispatcher :: SendMessageé¢æ°ã§CDispatcher :: m_Lockããã£ããã£ããg_Lockã°ããŒãã«åæãªããžã§ã¯ãããã£ããã£ããããšããŸãïŒãŠã£ã³ããŠãšåæ§ã«ãSendMessageã·ã¹ãã é¢æ°ãåŒã³åºããŸãïŒã
ãŠã£ã³ããŠãããŒA-> B
ã¯ãŒã¯ãããŒB-> A
ããã¯ãå€å
žçãªãããããã¯ãšåŒã°ããŸãã
åé¡ã¯ãé¢æ°CDispatcher :: SendMessageïŒïŒã«ãããŸãã
ããã§ã¯ãã«ãŒã«ãé å®ããå¿
èŠããããŸã-åæãªããžã§ã¯ãã®ãã£ããã£äžã«ã³ãŒã«ããã¯é¢æ°ãåŒã³åºãããšã¯ã§ããŸããã
ãã®ãããéç¥ãéä¿¡ãããšãã«ããã¯ã解é€ããŸãã
void SendMessage(void* pContext) { CSubscriberList SubscriberList; { CScopeLocker ScopeLocker(m_Lock); SubscriberList = m_SubscriberList; } for(size_t i = 0; i < SubscriberList.size(); ++i) { SubscriberList[i]->MessageHandler(pContext); } }
å å
¥è
ã®å¯¿åœç®¡ç
ãããããã¯ãåé€ãããšãå¥ã®åé¡ãçºçããŸãã-ãµãã¹ã¯ã©ã€ããããªããžã§ã¯ãã®å¯¿åœã§ãã
UnsubscribeãåŒã³åºããåŸã«MessageHandlerã¡ãœãããåŒã³åºãããªããšããä¿èšŒã¯ãªããªããŸããããã®ãããUnsubscribeãåŒã³åºããçŽåŸã«ãµãã¹ã¯ã©ã€ããªããžã§ã¯ããåé€ããããšã¯ã§ããŸããã
ãã®å Žåãæãç°¡åãªæ¹æ³ã¯ããªã³ã¯ã«ãŠã³ã¿ãŒã䜿çšããŠãµãã¹ã¯ã©ã€ããããªããžã§ã¯ãã®æå¹æéãå¶åŸ¡ããããšã§ãã
ãããè¡ãã«ã¯ãCOMãã¯ãããžã䜿çšã§ããŸã-ISubknownããCSubscriberã€ã³ã¿ãŒãã§ã€ã¹ãç¶æ¿ãããµãã¹ã¯ã©ã€ããªããžã§ã¯ãã®ãªã¹ãã«ATL CComPtrã䜿çšããŸããã€ãŸããstd :: vector <CSubscriber *>ãstd :: vector <CComPtr>ã«çœ®ãæããŸãã
ãããããã®ãããªå®è£
ã«ã¯ããããããAddRef / Releaseããã³äžèŠãªQueryInterfaceã¡ãœãããå®è£
ããå¿
èŠãããããããµãã¹ã¯ã©ã€ãã¯ã©ã¹ã®å®è£
ã«è¿œå ã®ã³ã¹ããããããŸããããããžã§ã¯ããCOMãç©æ¥µçã«äœ¿çšããŠããå Žåããã®ã¢ãããŒãã«ã¯å©ç¹ããããŸãã
ã¹ããŒããã€ã³ã¿ãŒã¯ããªã³ã¯ã«ãŠã³ã¿ãŒã䜿çšããŠãµãã¹ã¯ã©ã€ããããªããžã§ã¯ãã®æå¹æéãå¶åŸ¡ããã®ã«é©ããŠããŸãã
ãã«ãã¹ã¬ããç°å¢ã®ã·ã³ãã«ãªå®è£
typedef unsigned __int64 SubscriberId; class CSubscriber { public: virtual ~CSubscriber(){} virtual void MessageHandler(void* pContext) = 0; SubscriberId GetSubscriberId() {return (SubscriberId)this;} }; typedef boost::shared_ptr<CSubscriber> CSubscriberPtr; class CDispatcher { private: typedef std::vector<CSubscriberPtr> CSubscriberList; public: SubscriberId Subscribe(CSubscriberPtr pNewSubscriber) { CScopeLocker ScopeLocker(m_Lock); for(size_t i = 0; i < m_SubscriberList.size(); ++i) { if(m_SubscriberList[i]->GetSubscriberId() == pNewSubscriber->GetSubscriberId()) { return 0; } } m_SubscriberList.push_back(pNewSubscriber); return pNewSubscriber->GetSubscriberId(); } bool Unsubscribe(SubscriberId id) { CSubscriberPtr toRelease; CScopeLocker ScopeLocker(m_Lock); for(size_t i = 0; i < m_SubscriberList.size(); ++i) { if(m_SubscriberList[i]->GetSubscriberId() == id) { toRelease = m_SubscriberList[i]; m_SubscriberList.erase(m_SubscriberList.begin() + i); return true; } } return false; } void SendMessage(void* pContext) { CSubscriberList SubscriberList; { CScopeLocker ScopeLocker(m_Lock); SubscriberList = m_SubscriberList; } for(size_t i = 0; i < SubscriberList.size(); ++i) { SubscriberList[i]->MessageHandler(pContext); } } private: CSubscriberList m_SubscriberList; CLock m_Lock; };
ãã®å®è£
ã§ã¯ãCSubscriber *ã®ããã¢ããã€ã³ã¿ãŒãåç
§ã«ãŠã³ã¿ãŒä»ãã®ãã¹ããŒãããã€ã³ã¿ãŒã«çœ®ãæããŸãããããã¯ãããŒã¹ãã©ã€ãã©ãªã«ããããšãå€æããŸããã
ãŸããUnlockãåŒã³åºããåŸã«ãµãã¹ã¯ã©ã€ããŒãªããžã§ã¯ãã®ãã¹ãã©ã¯ã¿ãŒãåŒã³åºãããã«ãToReleaseå€æ°ãUnsubscribeé¢æ°ã«è¿œå ããŸããïŒåæãªããžã§ã¯ãããã£ããã£ããŠããéããµãã¹ã¯ã©ã€ããŒãªããžã§ã¯ãã®ãã¹ãã©ã¯ã¿ãŒãå«ãã³ãŒã«ããã¯é¢æ°ãåŒã³åºãããšã¯ã§ããŸããïŒã
SendMessageé¢æ°ãã¹ããŒããã€ã³ã¿ãŒã®ãªã¹ããã³ããŒããããšã¯æ³šç®ã«å€ããŸãïŒã³ããŒåŸããã¹ãŠã®ãã€ã³ã¿ãŒã¯åç
§ã«ãŠã³ããå¢ãããé¢æ°ãçµäºãããšæžå°ãããµãã¹ã¯ã©ã€ããªããžã§ã¯ãã®æå¹æéãå¶åŸ¡ããŸãïŒ
ãã¹ãäž
CDispatcher g_Dispatcher; CLock g_Lock; class CListener: public CSubscriber { virtual void MessageHandler(void* pContext) {
ãã«ãã¹ã¬ããç°å¢åãã«æé©åãããå®è£
ååãšããŠãSendMessageé¢æ°ã¯ãSubscribe / Unsubscribeãããã¯ããã«é »ç¹ã«åŒã³åºãããŸãã å€æ°ã®ãµãã¹ã¯ã©ã€ããŒã®å Žåãããã«ããã¯ã¯SendMessageå
ã®ãµãã¹ã¯ã©ã€ããŒã®ãªã¹ããã³ããŒããããšã§ãã
賌èªè
ã®ãªã¹ãã®ã³ããŒã¯ã賌èª/賌èªè§£é€æ©èœã«è»¢éã§ããŸãã ããã¯ãããã¯ããªãŒã¢ã«ãŽãªãºã ã®ææ³ã«äŒŒãŠããŸãã
CDispatcherãªããžã§ã¯ãã¯ããµãã¹ã¯ã©ã€ããŒã®ãªã¹ããçŽæ¥ä¿åããã®ã§ã¯ãªããã¹ããŒããã€ã³ã¿ãŒã䜿çšããŠä¿åããŸãã SendMessageé¢æ°å
ã§ããµãã¹ã¯ã©ã€ããŒã®çŸåšã®ãªã¹ããžã®ãã€ã³ã¿ãŒãååŸããŠæäœããŸãã Subscribe / Unsubscribeé¢æ°ã§ã¯ãæ¯åæ°ãããµãã¹ã¯ã©ã€ããŒã®ãªã¹ããäœæããCDispatcherãªããžã§ã¯ãå
ã®ãã€ã³ã¿ãŒãæ°ãããµãã¹ã¯ã©ã€ããŒã®ãªã¹ãã«ãªãã€ã¬ã¯ãããŸãã ãããã£ãŠãCDispatcherãªããžã§ã¯ãå
ã®ãµãã¹ã¯ã©ã€ããŒã®ãªã¹ããžã®ãã€ã³ã¿ãŒã¯æ¢ã«ãµãã¹ã¯ã©ã€ããŒã®æ°ãããªã¹ããæããŸãããSendMessageé¢æ°ã¯åŒãç¶ãå€ããªã¹ãã§æ©èœããŸãã ãµãã¹ã¯ã©ã€ããŒã®å€ããªã¹ããå€æŽãããŠãŒã¶ãŒã¯ããªãããããã¹ãŠããã«ãã¹ã¬ããç°å¢ã§å®å®ããŠåäœããŸãã
ååãšããŠãSubscribe / Unsubscribeã®æ©èœããããã«å€æŽããå®å
šã«ããã¯ããªãŒã®ã¢ã«ãŽãªãºã ãå®è£
ã§ããŸãããããã¯å¥ã®ãããã¯ã§ãã
賌èªè§£é€Medotã¯éåæã§ãããå®äºåŸã«ã¡ãŒã«éä¿¡ã®å®å
šãªåæ¢ãä¿èšŒãããã®ã§ã¯ãããŸãããååã®è§£æ±ºçã§ãã賌èªè
ã¯UnsubscribeHandleré¢æ°ã䜿çšããŠè³Œèªè§£é€ã«é¢ããéç¥ãåãåããŸãã ãã®åäœãå®è£
ããããã«ããã¹ãã©ã¯ã¿ã§UnsubscribeHandleré¢æ°ãåŒã³åºãäžéã¯ã©ã¹CSubscriberItemãè¿œå ãããŸããã
namespace Observer {
åç
§è³æ
Boostã©ã€ãã©ãª:: Signals2ã®
èšäº
ã¹ããŒããã€ã³ã¿ãŒ
ãžã§ãã¢ã«ãžã£ãŒ
ãªãœãŒã¹ååŸã¯åæåïŒRAIIïŒ
ãŠã£ãããã£ã¢
ãã®èšäºã®æåã®ããŒãžã§ã³ã«é¢ããã³ã¡ã³ãã¯
ãã¡ãã«ãããŸãã