চাইল্ড স্টেট মেশিন কীভাবে প্যারেন্ট স্টেট মেশিনের নিয়ন্ত্রণ ছেড়ে দিতে পারে?


9

আমার শীর্ষ স্তরের রাজ্য মেশিনের কয়েকটি রাজ্য এবং প্রান্ত রয়েছে। আমি এটিকে প্যারেন্ট স্টেট মেশিন বলব।

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

প্যারেন্ট স্টেট মেশিনের মধ্যে যে কোনও রাজ্যও রাষ্ট্রীয় মেশিন হতে পারে। আমি এই শিশুদের রাষ্ট্র মেশিন কল করব।

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

যদি প্যারেন্ট স্টেট মেশিনটি এ থেকে বিতে স্থানান্তরিত হয় তবে বি এর রাষ্ট্রীয় মেশিনটি গ্রহণ করে। একবার খ চালানো হয়ে গেলে, কীভাবে প্যারেন্ট স্টেট মেশিনের নিয়ন্ত্রণ ছেড়ে দেওয়া এবং সি সি তে রূপান্তর করা উচিত? আপনি কোন নকশার প্যাটার্ন ব্যবহার করেন?

আপনি যদি ভাবছেন তবে আমার পিতা বা মাতা রাষ্ট্রের মেশিনগুলির মধ্যে বাচ্চাদের রাষ্ট্রীয় মেশিন রয়েছে কারণ আমার সঠিক প্রকল্পটি বেশ জটিল এবং একটি শিশু রাষ্ট্রের অভ্যন্তরীণ কাজগুলি সজ্জিত করা স্বাভাবিক।


আমি অনুমান করেছিলাম যে বি0, বি 1, এবং বি 2 জানতে হবে যে তারা বাইরের বিশ্বকে একটি একক হিসাবে বিবেচনা করে এমন কোনও কিছুর উপাদান। সুতরাং সম্ভবত আপনার কাছে একটি MachineContainerক্লাস থাকতে হবে যার জন্য Bবি0, বি 1, এবং বি 2 রয়েছে এবং বি 2 শেষ হলে এটি তার ধারকটিতে নিয়ন্ত্রণ ফিরে আসে যা সিতে রূপান্তরিত হয় ... আমি আসলে এর আগে কখনও এর চেষ্টা করি নি। এটি একটি আকর্ষণীয় সমস্যা!
হতাশ

2
আপনার প্রশ্নের হয় হয় সুস্পষ্ট উত্তর বা আপনার প্রশ্ন খুব পরিষ্কার নয়। পিতামাতার দৃষ্টিকোণ থেকে, আপনি এটিকে ঠিক এমনভাবে প্রয়োগ করা উচিত যেমন আপনি এমন একটি রাষ্ট্রীয় মেশিন প্রয়োগ করেন যাতে শিশু রাষ্ট্র মেশিন নেই। এটি ঠিক তাই ঘটে যে চাইল্ড স্টেট মেশিন ব্যবহার করে রাজ্যগুলি প্রয়োগ করা হয় তবে এটি পিতামাতাকে মোটেই প্রভাবিত করে না। শিশুদের রাষ্ট্রীয় মেশিনগুলি প্রস্থান করার বাইরেও কেবল পিতামাতার স্তরের ইভেন্টগুলি তৈরি করে তা এটিকে প্রভাবিত করা উচিত নয়।
ডাঙ্ক

উত্তর:


5

প্রতিটি রাষ্ট্রের মেশিনে কিছু ইভেন্ট ইভেন্ট হ্যান্ডলার থাকে এবং এই ইভেন্টগুলিকে ট্রিগার করতে একটি উপায় থাকে। এই হ্যান্ডলারটি ইনপুট হিসাবে বিদ্যমান অবস্থা এবং ইভেন্টের ধরণ হিসাবে নেয়, নতুন রাজ্যটি চয়ন করে এবং optionচ্ছিকভাবে কিছু পার্শ্ব প্রতিক্রিয়া কোড চালায়।

মূলত, রাজ্যে থাকাকালীন B, আপনার মূল ইভেন্ট হ্যান্ডলার এমন কোনও ইভেন্ট ফরোয়ার্ড করে যা এটির ইভেন্ট হ্যান্ডলারের কাছে স্বীকৃতি দেয় না Bএবং অবস্থায় থাকে B। যখন Bরূপান্তর করতে চায় C, এটি মূল ইভেন্ট হ্যান্ডলারের কাছে উপযুক্ত ইভেন্টটি পোস্ট করে।


2

আপনি কি তাউপের এই বিভাগটি পড়েছেন ? এটি সম্পাদন করার বিভিন্ন উপায় রয়েছে তবে তাদের মধ্যে অনেকগুলি নির্ভর করে যে আপনি কীভাবে আপনার রাষ্ট্রীয় মেশিনগুলিকে বিভক্ত করেছেন। তারা পৃথক প্রক্রিয়া হয়? টপিক? অবজেক্টস?

আপনি সেগুলি কীভাবে তৈরি করেছেন তা নির্ধারণ করুন এবং তাদের যোগাযোগের কোনও প্রমিত উপায় আছে কিনা তা দেখুন। যদি কোনওটির অস্তিত্ব না থাকে তবে আপনি আপনার সিস্টেমটিকে ভুল ডিজাইন করতে পারেন।

আমার জন্য, আমি পৃথক প্রক্রিয়াগুলি দেখব, স্টিডিন এবং স্টাডআউটকে একত্রে হুকিং করব। চাইল্ড স্টেট মেশিনটি তখন স্ট্যান্ডলোন হয়ে যায়, স্টিডিনে অভিনয় করে এবং স্ট্যান্ডআউট এ আউটপুট দেয়। সন্তানের প্রক্রিয়া শুরু করা, পাইপগুলি হুক করা এবং তারপরে ডেটা ফেলে রাখা এবং ফলাফলের জন্য অপেক্ষা করা পিতামাতার রাষ্ট্র মেশিনের কাজ হয়ে যায়। এই সমস্ত জিনিস ইতিমধ্যে সমস্ত আধুনিক ভাষায় সম্পন্ন হয়েছে, তাই এটি করা সহজ হওয়া উচিত।


1

দুটি রাষ্ট্রীয় মেশিন পৃথক করুন এবং তাদের মধ্যে পাসিং বার্তা ব্যবহার করুন। সুতরাং, রাজ্য মেশিন 1 এবিসি থেকে অগ্রসর হবে, যেখানে রাজ্য বিতে এটি স্টেট মেশিনের 2 থেকে বর্তমান ফলাফলগুলি পরীক্ষা করে If রাষ্ট্র মেশিন 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) একটি সাধারণ পিতামাতার কাছ থেকে AB এবং C প্রাপ্ত করুন। যদি তাদের একটি সাধারণ অভিভাবক থাকে এবং দৃশ্যমানতা সর্বজনীন হয়, আপনার বি এর উপ-রাজ্য থেকে এ এর ​​উপরাষ্ট্রে যেতে খুব বেশি সমস্যা হবে না।

আপনি যদি এটিকে নাম স্থান এবং / অথবা এ, বি এবং সি এর সাধারণ পিতা বা মাতা না করে পৃথক করে থাকেন তবে আপনার সর্বোত্তম উপায় হ'ল এ, বি এবং সি মেশিনের জন্য একটি বাহ্যিক রাষ্ট্র পরিবর্তন ড্রাইভারকে ছড়িয়ে দেওয়া। এটি ইভেন্ট ইভেন্টের মাধ্যমে করা যেতে পারে। কেবল এ-তে একটি পর্যবেক্ষক থাকবেন যা বিতে উত্থাপিত ইভেন্টগুলি শুনতে পারে এবং ইভেন্টের উপর ভিত্তি করে নিজস্ব উপ-রাজ্যে রূপান্তর করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.