चाइल्ड स्टेट मशीन मूल राज्य मशीन को वापस कैसे नियंत्रित कर सकती है?


9

मेरी शीर्ष स्तर की राज्य मशीन में कुछ राज्य और किनारे हैं। मैं इसे पैरेंट स्टेट मशीन कहूंगा।

A ----> B ----> C

मूल राज्य मशीन के भीतर कोई भी राज्य एक राज्य मशीन भी हो सकती है। मैं इन बच्चों को स्टेट मशीन कहूंगा।

           ___________
         /            \
A ----> |  B0->B1->B2  | ----> C
         \____________/

यदि पैरेंट स्टेट मशीन A से B तक संक्रमण करती है, तो B की राज्य मशीन पर नियंत्रण हो जाता है। एक बार बी चलने के बाद, इसे मूल राज्य मशीन पर नियंत्रण और राज्य सी में संक्रमण से कैसे छुटकारा पाना चाहिए? आप किस डिज़ाइन पैटर्न का उपयोग करते हैं?

यदि आप सोच रहे हैं, तो मेरे पास माता-पिता राज्य मशीनों के भीतर बच्चे राज्य मशीनें हैं, क्योंकि मेरी सटीक परियोजना काफी जटिल है और बच्चे के राज्य के आंतरिक कामकाज को बाधित करना स्वाभाविक है।


मुझे लगता है कि B0, B1 और B2 को पता होना चाहिए कि वे किसी ऐसी चीज के घटक हैं जिसे बाहरी दुनिया एक इकाई मानती है। तो शायद आपके पास एक MachineContainerवर्ग होना चाहिए Bजिसमें B0, B1 और B2 शामिल हों और जब B2 समाप्त होता है, तो यह वापस अपने कंटेनर में नियंत्रण पारित करता है जो तब C को संक्रमण करता है ... मैंने वास्तव में ऐसा कुछ भी कभी नहीं किया है। यह एक दिलचस्प समस्या है!
FrustratedWithFormsDesigner

2
आपके प्रश्न का या तो स्पष्ट उत्तर है या आपका प्रश्न बहुत स्पष्ट नहीं है। माता-पिता के दृष्टिकोण से, आपको इसे ठीक उसी तरह लागू करना चाहिए जैसे आप एक राज्य मशीन को लागू करेंगे जिसमें बाल राज्य मशीनें नहीं हैं। यह सिर्फ इतना होता है कि राज्यों को बाल राज्य मशीनों का उपयोग करके लागू किया जाता है लेकिन यह माता-पिता को बिल्कुल प्रभावित नहीं करता है। यह बच्चों के राज्य मशीनों को प्रभावित नहीं करना चाहिए, क्योंकि वे केवल माता-पिता के स्तर की घटनाओं को उत्पन्न करते हैं।
डंक

जवाबों:


5

हर स्टेट मशीन में किसी न किसी तरह का इवेंट हैंडलर होता है और उन घटनाओं को ट्रिगर करने का एक साधन होता है। वह हैंडलर मौजूदा स्थिति के इनपुट के रूप में लेता है और घटना के प्रकार, नए राज्य को चुनता है, और वैकल्पिक रूप से कुछ साइड इफेक्ट कोड चलाता है।

अनिवार्य रूप से, राज्य में रहते हुए B, आपका मुख्य ईवेंट हैंडलर किसी भी ईवेंट को आगे बढ़ाता है, जो ईवेंट हैंडलर को नहीं पहचानता है Bऔर वह राज्य में रहता है B। जब Bसंक्रमण करना चाहता है C, तो यह मुख्य ईवेंट हैंडलर को उपयुक्त घटना पोस्ट करता है।


2

क्या आपने Taoup का यह खंड पढ़ा है ? इसे पूरा करने के कई अलग-अलग तरीके हैं लेकिन उनमें से कई इस बात पर निर्भर करते हैं कि आपने अपनी राज्य मशीनों को कैसे विभाजित किया है। क्या वे अलग-अलग प्रक्रियाएं हैं? धागे? वस्तुओं?

पता लगाएँ कि आपने उन्हें कैसे बनाया है, और यह देखने के लिए देखें कि क्या उनके लिए संवाद करने के लिए एक विहित तरीका है। यदि कोई मौजूद नहीं है, तो आप अपने सिस्टम को गलत बना सकते हैं।

मेरे लिए, मैं अलग-अलग प्रक्रियाओं को देखूंगा, स्टिंग और स्टडआउट को एक साथ हुक करूंगा। बाल राज्य मशीन तब स्टैंडअलोन बन जाती है, स्टड पर अभिनय करती है और स्टडआउट पर आउटपुट करती है। यह बच्चे की प्रक्रिया शुरू करने, पाइप को हुक करने और फिर डेटा में डंप करने और परिणामों की प्रतीक्षा करने के लिए मूल राज्य मशीन का काम बन जाता है। उन सभी चीजों को पहले से ही सभी आधुनिक भाषाओं में किया गया है, इसलिए इसे करना आसान होना चाहिए।


1

दो राज्य मशीनों को अलग करें और उनके बीच गुजरने वाले संदेश का उपयोग करें। इस प्रकार, राज्य मशीन 1 एबीसी से आगे बढ़ेगा, जहां राज्य बी में यह राज्य मशीन से वर्तमान परिणामों की जांच करता है। यदि आउटपुट बदल गया है, तो राज्य मशीन 1 इसके लिए जिम्मेदार हो सकता है और राज्य मशीन 2 को किसी भी जागरूकता की आवश्यकता नहीं है कैसे राज्य मशीन 1 वास्तव में काम करता है। कुछ इस तरह:

typedef struct StateMachine {
  void(*Update)(); // function to update the state machine
  int Data;        // generic temp holder to survive state contexts
  int State;       // current state of our state machine
  int *Message;    // pointer to a shared integer for message passing
};

int main(void) {
  int Message = 0;
  /* NewStateMachine would malloc the struct, pass in the int reference
   * and function pointer as well as add it to a circularly linked list */
  NewStateMachine(&Message, MainLoop);
  NewStateMachine(&Message, MinorLoop);
  StateMachine *Current = StateMachine_CLL.First;

  for(;;) {
    Current->Update(Current); /* Update the current state machine */
    Current = Current->Next;  /* And the advance to the next one */
  }
}

void MainLoop(StateMachine *this) {
  switch(this.State) {
  case 0:
    CloseCoolantTank(1); /* safe to call if valve already closed */
    CloseCoolantTank(2); /* safe to call if valve already closed */
    this.State = 1;
    break;
  case 1:
    /* we have a message, do something */
    if(*this.Message) this.State = 2;          
    /* otherwise stall at this state until we get a message */
    else this.State = 1;          
    break;
  case 2:
    if(*this.Message == 1) this.State = 3;      /* warm */
    else if(*this.Message == 2) this.State = 4; /* hot! */
    else this.State = 0;                        /* cooled down, shut off valves */
    this.Message = 0;                           /* clear the message */
    break;
  case 3:
    OpenCoolantTank(1); /* opens the valve, safe to call if already open */
    this.State = 2;     /* recheck for new message */
    break;
  case 4:
    OpenCoolantTank(2); /* opens the valve, safe to call if already open */
    this.State = 3;     /* also open coolant tank 1 for extra cooling */
    break;
  }
}

/* Monitor temperature and send messages on overheat */
void MinorLoop(StateMachine *this) {
  switch(this.State) {
  case 0:
    this.Data = ReadADCValue();
    this.State = 1;
    break;
  case 1:
    if(this.Data > 150) *this.Message = 2;
    else if(this.Data > 100) *this.Message = 1;
    this.State = 0;
    break;
  }
}

1

समाधान 1 पर निर्भर करता है) क्या ए के उप-राज्य बी के उप-राज्यों के लिए स्पष्ट हैं। 2) एक आम अभिभावक से एबी और सी प्राप्त करें। यदि उनके पास एक सामान्य अभिभावक है और दृश्यता सार्वभौमिक है, तो आपको B की उप अवस्था से A की उप अवस्था में जाने में बहुत अधिक परेशानी नहीं होनी चाहिए।

यदि आपने उन्हें नामस्थान और / या ए, बी और सी के माध्यम से अलग किया है, तो उनके पास एक सामान्य अभिभावक नहीं है, तो आपका सबसे अच्छा तरीका ए, बी और सी मशीनों के लिए एक बाहरी राज्य परिवर्तन चालक है। एक घटना हैंडलर के माध्यम से किया जा सकता है। बस ए में एक पर्यवेक्षक होता है जो बी में उठने वाली घटनाओं को सुनता है और घटना के आधार पर अपने स्वयं के उप-राज्य में बदलाव कर सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.